Сохранение содержимого UITextField перед всплывающими окнами просмотра

StackOverflow https://stackoverflow.com/questions/4061788

Вопрос

Я уверен, что это есть в документации 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;
}

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

[...] Входящий вид появится в главном представлении.
[...] Редактирование объекта
[...] На видуПропадет
[...] -- Мы не в стеке контроллера...была нажата кнопка «Назад»
[...] Входящий вид появится в главном представлении.
[...] В textFieldShouldEndEditing
[...] В textFieldEditingEnded
[...] В textFieldDidEndEditing

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

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

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

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

Это было полезно?

Решение

Хорошо, я нашел простое решение после долгого веб-серфинга, чтения форумов и чтения руководств.Как я и подозревал, все было очень просто, добавлена ​​всего одна строка кода.в 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];
}

И уже существующие методы для обработки кнопки «Возврат» на клавиатуре также обрабатывают кнопку «Назад» на контроллере навигации.

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

Другие советы

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

Я думаю, что с точки зрения 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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top