Text Input and Presenting Content Modally
A keyboard is presented automatically when a user selects a text container.
In IB you can select text input traits for your container. Likewise the
keyboard will be dismissed automatically when the user is finished with it.
When a user is being asked to pick or add data, often a view will be
presented modally which means the user must take an action and then return back.
Presenting and dismissing a view modally is done with the methods:
[self presentModalViewController:
viewController animated:YES];
and
[self dismissModalViewControllerAnimated:YES];
It is best practice for the same object to do both the call to present and dismiss. A good way to achieve this is to define delegate methods for the presented controller which tell the delegate when the presented controller is done. The parent controller is then made the delegate so that it can dismiss the controller at the appropriate time.
Here is an example. We define a view controller which will present a textField in which the user can type something. This view controller defines a delegate protocol with the method -typeSomethingViewController: didTypeSomething: which will be implemented by the delegate a invoked when the typing is complete. Also a delegate property is defined in the class. Here is the header file:
// TypeSomethingViewController.h
#import <UIKit/UIKit.h>
@protocol TypeSomethingViewControllerDelegate;
@interface
TypeSomethingViewController : UIViewController {
UITextField *textField;
id<TypeSomethingViewControllerDelegate> delegate;
}
@property (retain) IBOutlet
UITextField *textField;
@property (assign) id<TypeSomethingViewControllerDelegate>
delegate;
- (IBAction)doneButtonPressed:(id)sender;
@end
@protocol TypeSomethingViewControllerDelegate <NSObject>
@optional
- (void)typeSomethingViewController:(TypeSomethingViewController *)controller didTypeSomething:(NSString *)text;
@end
Now in the implementation of the class we need to define the
doneButtonPressed: method which will invoke the delegate method
typeSomethingViewController: didTypeSomething: with the parameter values of
itself and the text that was entered in the textField. This method will be
giving the text to the delegate after it is entered. Here is the .m file:
//
TypeSomethingViewController.m
#import "TypeSomethingViewController.h"
@implementation TypeSomethingViewController
@synthesize textField;
@synthesize delegate;
- (IBAction)doneButtonPressed:(id)sender{
if ([self.delegate respondsToSelector:@selector(typeSomethingViewController:didTypeSomething:)])
{
[self.delegate typeSomethingViewController:self didTypeSomething:textField.text];
}
}
- (void)dealloc {
[textField
release];
[super
dealloc];
}
@end
Now we will look at the parent controller which will present and dismiss the TypeSomethingViewController and will implement the TypeSomethingViewControllerDelegate. Firstly the ParentViewController.h will need to specify that this class implements the TypeSomethingViewControllerDelegate.
// ParentViewController.h
#import <UIKit/UIKit.h>
#import "TypeSomethingViewController.h"
@interface ParentViewController :
UIViewController < TypeSomethingViewControllerDelegate> {
. . .
}
. . .
@end
Suppose the ParentViewController has a method showTypeSomething: where it is
going to present the TypeSomethingViewController modally. Within this
method the parent will create a TypeSomethingViewController object, set itself
as the delegate and present the view controller:
- (IBAction)showTypeSomething:(id)sender
{
TypeSomethingViewController *typeSomethingViewController = [[TypeSomethingViewController
alloc] init];
typeSomethingViewController.delegate = self;
[self presentModalViewController:typeSomethingViewController animated:YES];
[typeSomethingViewController release];
}
Finally the ParentViewController will need to implement the delegate method
which will presumably do something with the text that was typed and dismiss the
TypeSomethingViewController.
- (void)typeSomethingViewController:(TypeSomethingViewController
*)controller didTypeSomething:(NSString *)text {
typeSomethingLabel.text = text;
[self dismissModalViewControllerAnimated:YES];
}