Сохранение содержимого UITextField перед всплывающими окнами просмотра
-
27-09-2019 - |
Вопрос
Я уверен, что это есть в документации 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;
}