Использование одного и того же View Controller для добавления, отображения и редактирования - PullRequest
5 голосов
/ 11 апреля 2011

Я работаю над приложением для iOS, которое использует очень распространенное табличное представление на основе Core Data для отображения элементов, и когда оно выбрано, оно отображает более подробный вид, очень похожий на приложение Contacts. Сам подробный вид представляет собой программно сгенерированную сгруппированную таблицу с настраиваемым (определяемым пером) видом для заголовка, который имеет изображение и имя. Некоторые из ячеек в таблице являются пользовательскими ячейками, которые имеют имя метки и значение текстового поля. В режиме «редактирования» ячейки редактируемой таблицы (и имя в заголовке) имеют .clearButtonMode, установленный в UITextFieldViewModeAlways, чтобы показать, что они доступны для редактирования.

В настоящее время я использую тот же контроллер представления для отображения подробной информации, редактирования информации и добавления новой записи в исходный список.

Когда добавляется новый элемент, контроллер представления создается модально с пользовательской перегрузкой init, которая устанавливает флаг в контроллере представления, чтобы указать, что он добавляет запись. Это позволяет запустить его в режиме редактирования, и если режим редактирования оставлен, вид модели пропадает. Правая кнопка меню - это обычная кнопка Редактировать / Готово, а левая - кнопка отмены. При редактировании существующего элемента левая кнопка (обычная кнопка возврата) заменяется кнопкой отмены.

Я начинаю задумываться о том, стоит ли использовать один контроллер представления для трех разных режимов. Есть несколько вопросов, которые я не знаю, как решить.

1) Как узнать, что режим редактирования оставлен нажатием кнопки «Готово»? Есть ли действие для этого? Если нажата кнопка «Отмена», действие либо отменяет себя (режим добавления), либо восстанавливает предыдущие значения, покидает режим редактирования. Я полагаю, что мог бы поставить проверку в своем переопределении setEditing, чтобы справиться с этим, но, похоже, должен быть лучший способ.

2) При входе в режим редактирования и установке для редактируемых текстовых полей значения UITextFieldViewModeAlways, есть ли способ анимировать внешний вид кнопок «X», чтобы они исчезали вместе с индикаторами редактирования на обычных ячейках?

Существуют ли простые решения этих проблем или мой контроллер просмотра 3-в-1 - плохая идея? Неправильно переделывать одно и то же представление для разных режимов, но наличие нескольких режимов для контроллера представления выглядит немного хлопотно.

Jorj

Ответы [ 2 ]

3 голосов
/ 07 марта 2013

Мне нравится подход 3-в-1, и я использую его постоянно.Есть много преимуществ: одна XIB, один контроллер представления, один простой протокол между контроллерами списка и подробного представления.Да, есть еще несколько проверок типа if (self.editing) ..., но мне это нравится больше, чем большему количеству контроллеров представления и xibs.

Чтобы помочь с добавлением, я выставляю BOOL, который может установить делегат.

@property (nonatomic) BOOL adding;

1) Встроенный editButtonItem не позволяет вам перехватить его перед setEditing: animated: Это проблематично, когда вы выполняете проверку данных после нажатия кнопки «Готово».По этой причине я редко использую editButtonItem и использую свои собственные кнопки Edit, Done и Cancel с их собственными методами действий.См. Ниже.

2) Для этого мне нравится reloadSections UITableView: withRowAnimation.Это может работать в вашем случае.

- (void)edit:(id)sender 
{
    self.editing = YES;
}
- (void)done:(id)sender 
{
    // data validation here
    if (everythingChecksOut)
    {
      //save here
    } else {
      return; //something didn't validate
    }

    //if control reaches here all is good
    //let the delegate know what happened...
    if (self.adding) {
      [self.delegate didFinishAddingWithData:self.yourData];
    } else {
      [self.delegate didFinishEditingWithData:self.yourData];
    }

    self.adding = NO;
    self.editing = NO;
}
- (void)cancel:(id)sender
{
    [self.view endEditing:YES]; //in theory, forces the view that is editing to resign first responder
    //in practise I find it doesn't work with the YES parameter and I have to use my own flag

    // roll back any changes here

    self.editing = NO;

    if (self.adding) //let the delegate know we cancelled the add...
    {
        [self.delegate didCancelAdd];
    }
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    [super setEditing:editing animated:animated];

    //set your nav bar title
    [self.tableview.editing = editing]; //you may or may not require this
    [self.tableview reloadSections... withRowAnimation:yourChoice];

    if (editing)
    {
        //install your Done and Cancel buttons
    } else {
        //remove Cancel and put the Edit button back
    }
}

Тогда в viewDidLoad ...

- (void)viewDidLoad
{
    [super viewDidLoad];

    //whatever else you do

    if (self.adding)
    {
        self.editing = YES;
    }
}
1 голос
/ 15 апреля 2012

Я не полностью понял вопросы, которые вы подняли, но вот некоторые мысли о структуре, которые, вероятно, более полезны в первую очередь ...

Кажется, вы слишком много делаете с одним UITableViewController, и неизбежно у вас будет много операторов if и запутанного кода. Я бы разбил его на два отдельных UITableViewControllers, один для обработки основного вида (и любого последующего необходимого вам режима редактирования), а другой - для подробного представления. Затем любой из них или оба могут использовать перья по вашему усмотрению.

Использование двух подобных контроллеров позволит вам просто вставить второй detailViewController в стек навигации, а не представлять его модально, что в данном случае не кажется очевидным.

Однако, если вы предпочитаете, чтобы он отображался модально, вы можете написать протокол для detailView, который отправляет сообщения в случае нажатия кнопок «Отмена», «Редактировать» или «Готово». Первый viewController может затем реализовать протокол и получить эти события.

Надеюсь, это поможет ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...