I am sure this is in the Apple documentation or must have been answered somewhere on this forum, since it seems so basic, but I could not find it nor a particularly elegant solution myself.
What I have is a UIViewController that pushes an editing view on its navigation stack. The editing view has a bunch of UITextFields in it. If one of them is being editing when the back button is touched, the original view's ViewWillAppear method is called before either the UITextField delegate methods of textFieldShouldEndEditing
or textFieldDidEndEditing
, or the IB linked action textFieldEditingEnded
method are called.
Here is some code that I hope will make it clearer:
In the 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];
}
In the 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;
}
The log ends up with:
[...] Entering view will appear for master view
[...] Editing the object
[...] In viewWillDisappear
[...] -- We are not in controller stack... the back button has been pushed
[...] Entering view will appear for master view
[...] In textFieldShouldEndEditing
[...] In textFieldEditingEnded
[...] In textFieldDidEndEditing
I want to set self.editedObject.name = nameField.text
before the label gets set in viewWillAppear
for the UIViewController.
I thought about in the viewWillDisappear method for the EditViewController checking to see if any of my text fields are currently the first responder and if so getting their text and storing it, but this seems like such a kludge that will be a pain to maintain if I add or change text fields.
I can also implement the textFieldEditingChanged
IB linked action to set the text in the edited object after every keystroke but this is also quite a bit of overhead since I have to figure out which text field I am in every keystroke (remember I only showed name
but there are a whole bunch of them).
All I need is for the editing to be ended or to know the editing will be ended before viewWillAppear is called in the UIViewController so the nameFieldLabel is properly set.
OK, I figured out a simple solution after a lot of web-surfing, forum reading, and manual reading. It was, as I suspected, very simple, only one line of code added. In the viewWillDisappear
method of the EditViewContorller I simply added:
[self.view.window endEditing: YES];
Now textFieldShouldEndEditing
, textFieldEditingEnded
, and textFieldDidEndEditing
all get fired off before the viewWillAppear
of the master view does.
So now the viewWillDisappear
method looks like:
- (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];
}
And the methods already in place to handle the 'Return' on the keyboard also handle the 'Back' button on the Navigation controller.
Thank you Aaron and Jeff for your assistance and helping me think this through.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With