Сохранение содержимого UITextField перед просмотром

Я уверен, что это находится в документации Apple или, должно быть, где-то на этом форуме был дан ответ, поскольку он кажется таким базовым, но я не мог найти его ни особенно элегантным решением.

У меня есть UIViewController, который подталкивает представление редактирования в своем стеке навигации. В окне редактирования есть куча UITextFields. Если один из них редактируется при нажатии кнопки "Назад", метод "ViewWillAppear" исходного вида вызывается перед вызовом методов делегирования UITextField из textFieldShouldEndEditing или textFieldDidEndEditing или вызван метод IB с привязкой textFieldEditingEnded.

Вот какой код, который, я надеюсь, упростит:

В UIViewController:

- (void) viewWillAppear: (BOOL) animated {
    [super viewWillAppear: animated];
    NSLog( @"Entering view will appear for master view" );
    nameLabelField.text = objectToEdit.name;
}
- (IBAction) editMyObject: (id) sender {
    NSLog( @"Editing the object" );
    EditViewController *evc = [[EditViewController alloc] initWithNibName: @"EditTableView" bundle: nil];
    evc.editedObject = objectToEdit;
    [self.navigationController pushViewController: evc animated: YES];
    [evc release];
}

В EditViewController <UITextFieldDelegate> :

- (void) viewWillAppear: (BOOL) animated {
    [super viewWillAppear: animated];
    nameField.text = editedObject.name;
}
- (void) viewWillDisappear: (BOOL) animated {
    [super viewWillDisappear: animated];
    NSLog( @"In viewWillDisappear" );
    if( [self.navigationController.viewControllers indexOfObject: self] == NSNotFound ) {
        NSLog( @"-- We are not in controller stack... the back button has been pushed" );
    }
}
- (BOOL) textFieldShouldEndEditing: (UITextField *) textField {
    NSLog( @"In textFieldShouldEndEditing" );
    // Store text field value here???
    // editedObject.name = nameField.text;
    return YES;
}
- (void) textFieldDidEndEditing: (UITextField *) textField {
    NSLog( @"In textFieldDidEndEditing" );
    // Store text field value here???
    // editedObject.name = nameField.text;
}
- (IBAction) textFieldEditingEnded: (id) sender {
    NSLog( @"In textFieldEditingEnded" );
    // Store text field value here???
    // editedObject.name = nameField.text;
}

Журнал заканчивается:

[...] В главном представлении появится представление ввода

[...] Редактирование объекта
[...] В представленииWillDisappear
[...] - Мы не в стеке контроллера... нажата кнопка "Назад"
[...] В главном представлении появится представление [...] В textFieldShouldEndEditing
[...] В textFieldEditingEnded
[...] В textFieldDidEndEditing

Я хочу установить self.editedObject.name = nameField.text, прежде чем метка будет установлена ​​в viewWillAppear для UIViewController.

Я думал о методе viewWillDisappear для проверки EditViewController, чтобы проверить, является ли какое-либо из моих текстовых полей в настоящее время первым ответчиком, и если так получить их текст и сохранить его, но это похоже на такой kludge, который будет больно если я добавляю или изменяю текстовые поля.

Я также могу реализовать связанное с тегом textFieldEditingChanged IB, чтобы установить текст в отредактированном объекте после каждого нажатия клавиши, но это также довольно немного накладных расходов, так как я должен выяснить, какое текстовое поле я нахожу в каждом нажатии клавиши (помните Я показал только name, но есть целая куча).

Все, что мне нужно для завершения редактирования или для того, чтобы знать, что редактирование будет закончено до того, как viewWillAppear вызывается в UIViewController, поэтому имяFieldLabel правильно установлено.

Ответы

Ответ 1

ОК, я выяснил, что это простое решение после большого количества веб-серфинга, чтения в форумах и ручного чтения. Это было, как я подозревал, очень простым, добавилась только одна строка кода. В методе viewWillDisappear EditViewContorller я просто добавил:

    [self.view.window endEditing: YES];

Теперь textFieldShouldEndEditing, textFieldEditingEnded и textFieldDidEndEditing все срабатывают перед тем, как viewWillAppear главного представления.

Итак, теперь метод viewWillDisappear выглядит следующим образом:

- (void) viewWillDisappear: (BOOL) animated {
    [super viewWillDisappear: animated];
    NSLog( @"In viewWillDisappear" );
    // Force any text fields that might be being edited to end so the text is stored
    [self.view.window endEditing: YES];
}

И методы, которые уже существуют для обработки "Return" на клавиатуре, также обрабатывают кнопку "Back" на навигационном контроллере.

Спасибо Аарон и Джефф за вашу помощь и помогли мне это понять.

Ответ 2

Почему бы просто не создать свою собственную кнопку "Назад" с этой логикой в ​​своем методе действий?

Ответ 3

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

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

// add this to the field(s) to be edited, selector will be called as the changes
// are being made... still difficult to handle a cancel, but should work
[objectToEdit addTarget:self action:@selector(updateNameField:) 
                         forControlEvents:UIControlEventEditingChanged];

дополнительный код здесь...

// the method called to update object from parent view
- (void)updateNameField:(id)sender {
    <OBJECT TO UPDATE>.text = ((UITextField *)sender).text;
}