IPhone tutorials UIText field Handling Keyboard Interactions

IPhone tutorials UIText field Handling Keyboard Interactions
This Tutorials provide you with the process to get the return button working on the keypad that pops up while filling a text field, the “Background Tap” functionality, and also what to do when the text field hides behind the keypad.

First we make a demo View-based Application for this, say “BackgroundTapForBlog” .


Add a text field to BackgroundTapForBlogViewController.xib, declare it in your BackgroundTapForBlogViewController.h file ,say tfUsername and link them in .xib.
 
Return Button on KeyPad:

Once you are done with this, add a function “textFieldDoneEditing” to the BackgroundTapForBlogViewController.m file, and do not forget to declare it in the BackgroundTapForBlogViewController.h file. This function gets rid of the keypad once you are done filling in the textfield.

BackgroundTapForBlogViewController.h file -
1 #import

2 @interface BackgroundTapForBlogViewController: UIViewController{
3 UITextField *tfUsername;
4 }
5 @property(nonatomic, retain) IBOutlet UITextField *tfUsername;
6 -(IBAction) textFieldDoneEditing : (id) sender;
7 -(IBAction) backgroundTap:(id) sender;
8 @end

BackgroundTapForBlogViewController.m file -
01 #import "BackgroundTapForBlogViewController.h"

02
03 @implementation BackgroundTapForBlogViewController
04 @synthesize tfUsername;
05
06 - (void)viewDidUnload {
07 self.tfUsername = nil;
08 }
09
10 - (void)dealloc {
11 [tfUsername release];
12 [super dealloc];
13 }
14
15 -(IBAction) textFieldDoneEditing : (id) sender{
16 [sender resignFirstResponder];
17 }
18
19 -(IBAction) backgroundTap:(id) sender{
20 [self.tfUsername resignFirstResponder];
21 }
22 @end
Now, save your project (Command+S).

Finally, open BackgroundTapForBlogViewController.xib again and link the “textFieldDoneEditing” function from File’s Owner to your text field/fields, and select “DidEndOnExit” option.


Background Tap Functionality:
Other than the return button on the keypad, we do provide an option that the keypad should disappear if the user touches the background. This is done as follows -


Now go back to Xcode and declare a function “backgroundTap” in the BackgroundTapForBlogViewController.h file and add it to BackgroundTapForBlogViewController.m file.
 
1 -(IBAction) backgroundTap:(id) sender{

2 [self.tfUsername resignFirstResponder];
3 }

This function gets rid of the keypad. ResignFirstResponder notifies the receiver(in this case, tfUsername) that it is supposed to give up its status as first responder in the current window.


Save your project (Command+S).

Now, open BackgroundTapForBlogViewController.xib. Select UIView from the Main Window of Interface Builder and press Command+2 (open Connection Inspector). You will notice there is no option like touch up inside. So you need to change the class from UIView to UIControl in Identity Inspector (Command + 4). UIView is extended from UIControl, now events like touch up inside can be detected on a UIControl. Hence, this change.

Then select File’s Owner and link the function “backgroundTap” to the background of your view, and select option “Touch Up Inside” with UIControl. 
 
 

Text Field Hiding behind keypad:

When the text field/fields begin hiding behind the keypad, it becomes necessary to scroll up so that the text field would be visible while filling it from the keypad.
For this, we need to include 5 files viz.,
MIBackgroundTapDelegate.h,
MIScrollView.h
MIScrollView.m
ScrollableViewController.h
ScrollableViewController.m
Add these files to your project, and follow the instructions -

BackgroundTapForBlogViewController.h –
Extend our controller from “ScrollableViewController”. We no longer need a declaration for backgroundTap function, since we are implementing MIBackgroundTapDelegate which has a declaration for the same.
01 #import

02 #import "ScrollableViewController.h"
03 #import "MIBackgroundTapDelegate.h"
04
05 @interface BackgroundTapForBlogViewController:ScrollableViewController {
06 UITextField *tfUsername;
07 }
08 @property(nonatomic, retain) IBOutlet UITextField *tfUsername;
09 -(IBAction) textFieldDoneEditing : (id) sender;
10 //-(IBAction) backgroundTap:(id) sender;
11 @end
BackgroundTapForBlogViewController.m file-
01 #import "BackgroundTapForBlogViewController.h"

02
03 @implementation BackgroundTapForBlogViewController
04 @synthesize tfUsername;
05 - (void)viewDidLoad {
06 self.svScrollViewM.contentSize = CGSizeMake(320,416);
07 [self registerForEditingEvents:tfUsername];
08 [super viewDidLoad];
09 }
10
11 - (void)viewDidUnload {
12 self.tfusername = nil;
13 }
14 - (void)dealloc {
15 [tfUsername release];
16 [super dealloc];
17 }
18 -(IBAction) textFieldDoneEditing : (id) sender{
19 [sender resignFirstResponder];
20 }
21 -(IBAction) backgroundTap:(id) sender{
22 [self.tfUsername resignFirstResponder];
23 }
24 @end
25
26
27 MIBackgroundTapDelegate.h -
28 We declare a protocol for backgroundtap function.
29
30 [objc]
31 @protocol MIBackgroundTapDelegate
32 - (IBAction)backgroundTap:(id)sender;
33 @end
ScrollableViewController.h -

Declare properties and functions for the scroll view controller.
01 #import

02
03 @interface ScrollableViewController : UIViewController {
04 UIControl * ctrlKeyboardFocusFieldM;
05 BOOL bKeyboardShownM;
06 UIScrollView * svScrollViewM;
07 }
08
09 @property (nonatomic, retain) UIControl * ctrlKeyboardFocusFieldM;
10 @property (nonatomic, retain) IBOutlet UIScrollView * svScrollViewM;
11
12 - (void) registerForEditingEvents:(UIControl *) aControl;
13 - (void) registerForKeyboardNotifications;
14 - (void) keyboardWasHidden:(NSNotification*)aNotification;
15 - (void) keyboardWasShown:(NSNotification*)aNotification;
16 - (void) textFieldDidBeginEditing:(UITextField *)textField;
17 - (void) textFieldDidEndEditing:(UITextField *)textField;
18 @end
ScrollableViewController.m -
01 #import "ScrollableViewController.h"

02 @implementation ScrollableViewController
03 @synthesize ctrlKeyboardFocusFieldM;
04 @synthesize svScrollViewM;
05 - (void)viewDidLoad {
06 [self registerForKeyboardNotifications];
07 [super viewDidLoad];
08 }
09 - (void)didReceiveMemoryWarning {
10 // Releases the view if it doesn't have a superview.
11 [super didReceiveMemoryWarning];
12 }
13 - (void)viewDidUnload {
14 self.ctrlKeyboardFocusFieldM = nil;
15 self.svScrollViewM = nil;
16 }
17 - (void)dealloc {
18 [ctrlKeyboardFocusFieldM release];
19 [svScrollViewM release];
20 [super dealloc];
21 }
22 - (void)registerForKeyboardNotifications {
23 [[NSNotificationCenter defaultCenter] addObserver:self
24 selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
25 [[NSNotificationCenter defaultCenter] addObserver:self
26 selector:@selector(keyboardWasHidden:)
27 name:UIKeyboardDidHideNotification object:nil];
28 }
29
30 // Called when the UIKeyboardDidShowNotification is sent.
31 - (void)keyboardWasShown:(NSNotification*)aNotification{
32 if (bKeyboardShownM)
33 return;
34
35 NSDictionary* info = [aNotification userInfo];
36
37 // Get the size of the keyboard.
38 NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
39 CGSize keyboardSize = [aValue CGRectValue].size;
40
41 // Resize the scroll view (which is the root view of the window)
42 CGRect viewFrame = [self.svScrollViewM frame];
43 viewFrame.size.height -= keyboardSize.height;
44 self.svScrollViewM.frame = viewFrame;
45
46 // Scroll the active text field into view.
47 CGRect textFieldRect = [self.ctrlKeyboardFocusFieldM frame];
48 [self.svScrollViewM scrollRectToVisible:textFieldRect animated:YES];
49 bKeyboardShownM = YES;
50 }
51
52 // Called when the UIKeyboardDidHideNotification is sent
53 - (void)keyboardWasHidden:(NSNotification*)aNotification{
54 NSDictionary* info = [aNotification userInfo];
55
56 // Get the size of the keyboard.
57 NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
58 CGSize keyboardSize = [aValue CGRectValue].size;
59
60 // Reset the height of the scroll view to its original value
61 CGRect viewFrame = [self.svScrollViewM frame];
62 viewFrame.size.height += keyboardSize.height;
63 self.svScrollViewM.frame = viewFrame;
64 bKeyboardShownM = NO;
65 }
66
67 - (void)textFieldDidBeginEditing:(UITextField *)textField{
68 self.ctrlKeyboardFocusFieldM = textField;
69 }
70
71 - (void)textFieldDidEndEditing:(UITextField *)textField{
72 self.ctrlKeyboardFocusFieldM = nil;
73 }
74
75 - (void) registerForEditingEvents:(UIControl*)aControl{
76 [aControl addTarget:self action:@selector(textFieldDidBeginEditing:)
77 forControlEvents:UIControlEventEditingDidBegin];
78 [aControl addTarget:self action:@selector(textFieldDidEndEditing:)
79 forControlEvents:UIControlEventEditingDidEnd];
80 }
81 @end
1.RegisterForKeyboardNotifications function is used to set notifications whenever keyboard is shown or hidden, and it accordingly, calls selector methods keyboardWasShown or keyboardWasHidden respectively.

2.In keyboardWasShown function, we obtain the keyboard frame size, and resize it from the scroll view’s frame size (which is equivalent to shifting the scroll upwards).Accordingly, we also move the active text field to a location above the keyboard so as to make it visible.
3.In keyboardWasHidden function, we add the keyboard size to the current frame size, to obtain the original size, and it also move the active textfield to its original position.
MIScrollView.h -
1 #import

2 #import "MIBackgroundTapDelegate.h"
3
4 @interface MIScrollView : UIScrollView {
5 id backgroundTapDelegate;
6 }
7
8 @property (nonatomic, retain) idbackgroundTapDelegate;
9 @end
MIScrollView.m -
01 #import "MIScrollView.h"

02 #import "MIBackgroundTapDelegate.h"
03
04 @implementation MIScrollView
05 @synthesize backgroundTapDelegate;
06
07 -(void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event {
08 if(backgroundTapDelegate) {
09 [backgroundTapDelegate backgroundTap: self];
10 }
11 }
12 @end
In the BackgroundTapForBlogViewController.xib, add a scrollview, move everything on top of the scrollview and resize it as per requirement. In its Identity Inspector(Command+4), change its class to MIScrollView.

Link this scrollview to svScrollViewM of File’s Owner.


Link delegate and backgroundTapDelegate of MIScrollView to File’s Owner.

Now, save your application in Xcode, and press Build & Go. When you select the textfield, the output would look like this -

You can download the source code from cinterviews here

No comments: