Thursday, March 28, 2013

Handling Soft Keypad in iPhone Tutorial


Handling the Soft Keyboard in iPhone application is bit painful stuff specially when we are beginner.
when I used text field first time after editing text I clicked on return key, Hit Enter bla bla..and I was shocked  What the hell.. keypad is locked and didn't go away, and even I was not able to see my other text fields and Login button those were hidden by keypad.

Then I started digging on it, how to handle keypad in this situation and got some tricky solutions and started using in my projects.

So Today I'll write Simple Tutorial to handle keypad in iOS applications

Please! stay with me, and do it step by step by .. don't forget to drop me a message or comment.

At the end of this Tutorial you can find Complete Source code zip file.

There are three simple ways to handle keypad here

1. Keypad go back when Button clicked.
2. Keypad go back when user click on Return or Done button on keypad.
3. Keypad go back when user Touch on Background screen/view. 



Note : This Application Developed Using : iOS 6.1 , Xcode 4.6, and MAC OS X Lion 10.8.3

PHASE - I (Create New Project)

So, Let's Fire Xcode!!

Go to File --> New --> Project

Now we can see a Pop up Window for selecting our application templet 

So make sure you Single View Application templet as shown in below picture and Go for Next..



In the Next Window we need to put Our Project Details this way

 ---------------------------------------------------------------
| Product Name : KeypadDemo                     |
| Organization Name :RDCWorld      |
| Company Identifier : com.rdcworld              |
|                              |
| Class Prefix :  (leave it blank for now)      |
|                              |
| Devices : iPhone                      |
 ----------------------------------------------------------------

Note : Don't forget to Make Tick mark on "Use Automatic Reference Counting" option.



Go to Next --> Create.

Now you can see Xcode default dashboard with our newly created project .

PHASE - II (Design UI)

Open ViewController.xib file

1. drag an UINavigationBar and double click on it --> put name "Handle Keypad" (It is just Title of app)

2. now drag two UITextFields for User Name and Password input.

3. select TextField --> go to Attributes Inspector --> put Placeholder as "enter username here"



4. do the same for other text field --> put Placeholder as "enter password here" 

5. drag UIButton from object library and double click on it, update name as "Login" --> save this file

6. change background colour to Blue (optional)




PHASE - III (Create IBOutlets and IBAction )


We need to create two IBOutlets for TextFields and an IBAction method for UIButton.

open ViewController.xib 

Okay, Now select Assistant Editor on Top Right side



You can see our ViewController.xib (Left side) + ViewController.h (Right side) opened together.

Create IBOutlets

1. Select Text Field for UserName-- > press Ctrl +Click and drag cursor  between @interface and @end  (in Right side Header File). 

2. in the pop up window, put name as "userNameTextField" and connect.

you will find one IBOutlet property is created in header file

@property (weak, nonatomic) IBOutlet UITextField *userNameTextField;

3.do the same for password Text Field, it will create below line of code in your header file.

@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;


Create IBActions

3.  select 'Keypad Go Back' Button -- > press Ctrl +Click and drag cursor  between @interface and @end  (in Right side Header File). 

4. in the pop up window make sure you change Connection = Action and give method name as "keypadGoBack" 

you will find one IBAction method is created in header file

- (IBAction)keypadGoBack:(UIButton *)sender;



3.  do the same for Login button and give method name as "loginButtonClicked"

you will find one IBAction method is created in header file and empty body is added in implementation file (.m file ) too

- (IBAction)loginButtonClicked:(id)sender;


Done!! now back to Standard Editor



At this time If you will run the application you will get stuck on keypad because so far we haven't any logic to handle this.


So here we go..

PHASE - IV (Writing Code)

~ ~ ~ ~ ~ ~ ~ ~ ~              Application Delegate Class (AppDelegate)          ~ ~ ~ ~ ~ ~ ~ ~ ~  

First is First!! Make sure your app delegate files code should be like given below

Finally our AppDelegate.h file look like 

---------------------------------------------------------------------------------------------------------------------------------------//
//  AppDelegate.h
//  KeypadDemo
//
//  Created by RDC on 28/03/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import <UIKit/UIKit.h>

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ViewController *viewController;

@end
-----------------------------------------------------------------------------------------------------------------------------------------

and Finally our AppDelegate.m file look like 

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  AppDelegate.m
//  KeypadDemo
//
//  Created by RDC on 28/03/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import "AppDelegate.h"

#import "ViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];    
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

//for now leave rest all empty methods..

@end
-----------------------------------------------------------------------------------------------------------------------------------------

There are three simple ways we will learn to handle keypad here

1. Keypad go back when Button clicked.
2. Keypad go back when user click on Return or Done button on keypad.
3. Keypad go back when user Touch on Background screen/view. 



1. Keypad go back when Button clicked

Generally we use this solution when we click on any button and keypad go away.

First make sure our ViewController.h file code should be like this

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.h
//  KeypadDemo
//
//  Created by RDC on 28/03/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *userNameTextField;
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;

- (IBAction)keypadGoBack:(id)sender;
- (IBAction)loginButtonClicked:(id)sender;

@end
-----------------------------------------------------------------------------------------------------------------------------------------
Okay let's do some code ..

open implementation class ViewController.m

1.  add synthesize (for all declared variable in header file with @property) just below to @implementation

@synthesize userNameTextField;
@synthesize passwordTextField;

3. add below code in keypadGoBack method body this way

- (IBAction)keypadGoBack:(id)sender {
    
    [userNameTextField resignFirstResponder];
    [passwordTextField resignFirstResponder];
}

That's it, Save file.

So This time our ViewController.m file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.m
//  KeypadDemo
//
//  Created by RDC on 28/03/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

@synthesize userNameTextField;
@synthesize passwordTextField;

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];    
}

- (IBAction)keypadGoBack:(id)sender {    
    [userNameTextField resignFirstResponder];
    [passwordTextField resignFirstResponder];
}

- (IBAction)loginButtonClicked:(id)sender {      
}
@end
-----------------------------------------------------------------------------------------------------------------------------------------

On this stage if you will run the application, you will see, when you click on KeypadGoBack the soft keypad goes away.


2. Keypad go back when user click on Return or Done button on keypad

Generally we use this solution when we click on Return or Done button and keypad go away.

This time we will implement UITextField delegate methods to handle Return key on soft keypad.

1. add UITextFieldDelegate in ViewController.h file's @interface this way

@interface ViewController : UIViewController<UITextFieldDelegate>

So This time our ViewController.h file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.h
//  KeypadDemo
//
//  Created by RDC on 28/03/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UITextFieldDelegate>

@property (weak, nonatomic) IBOutlet UITextField *userNameTextField;
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;

- (IBAction)keypadGoBack:(id)sender;
- (IBAction)loginButtonClicked:(id)sender;

@end
-----------------------------------------------------------------------------------------------------------------------------------------


now open implementation class ViewController.m

1. add below code in viewDidLoad method

userNameTextField.delegate =self;
passwordTextField.delegate =self;

//or same you can achieve by hookup TextField Delegate in InterfaceBuilder also

3. now  add  UITextFieldDelegate method just before @end

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}

That's it, Save file.

So This time our ViewController.m file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.m
//  KeypadDemo
//
//  Created by RDC on 28/03/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

@synthesize userNameTextField;
@synthesize passwordTextField;

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    userNameTextField.delegate =self;
    passwordTextField.delegate =self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];    
}

- (IBAction)keypadGoBack:(id)sender {
    
    [userNameTextField resignFirstResponder];
    [passwordTextField resignFirstResponder];
}

- (IBAction)loginButtonClicked:(id)sender {      
}

#pragma -mark UITextField delegate method

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}
@end
-----------------------------------------------------------------------------------------------------------------------------------------

On this stage if you will run the application, you will see, when you click on Keypad's Return/Done key soft keypad goes away.

3. Keypad go back when user Touch on Background screen/view. 

This one is my favourite solution, Where ever I am just need to touch on background view and keypad go like a flying Zebra.. :p

Easy and suitable in all situation

Let's make it real..

1. open ViewController.m file and and this method at the end of the file and before  @end

-(IBAction) touchOnBackground{
    [userNameTextField resignFirstResponder];
    [passwordTextField resignFirstResponder];
}


So This time our ViewController.m file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.m
//  KeypadDemo
//
//  Created by RDC on 28/03/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

@synthesize userNameTextField;
@synthesize passwordTextField;


#pragma mark - view controller's life cycle methods

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    userNameTextField.delegate =self;
    passwordTextField.delegate =self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];    
}

#pragma mark - Button click methods

- (IBAction)keypadGoBack:(id)sender {
    
    [userNameTextField resignFirstResponder];
    [passwordTextField resignFirstResponder];
}

- (IBAction)loginButtonClicked:(id)sender {      
}

#pragma -mark UITextField delegate method

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}

#pragma - mark method for touch on background 

-(IBAction) touchOnBackground{
    [userNameTextField resignFirstResponder];
    [passwordTextField resignFirstResponder];
}

@end
-----------------------------------------------------------------------------------------------------------------------------------------

2. now open ViewController.xib file --> select/click on background view (blue colour)

select Identity Inspector (In top right side) --> change Class = UIControl (default it's UIView)



3. now make sure your background still selected -->select Connections Inspector, you can see list of delegate method



so click on Touch Down method and drag cursor to Left side File Owner (Yellow Cube) --> select touchOnBackground as shown in below picture.



That's it save file and run application for the results.

This time if we click on anywhere on background , keypad will go away.

Great!! we did it.

here is the result screen



You can find complete project source code zip file here : KeypadDemo.zip (66.71 KB)

I Would love to here your thoughts !!

Tuesday, March 12, 2013

How to store info in application preferences iPhone (NSUserDefaults Tutorial)


Sometime we need to store, our application information on Application preference for short time.
iOS provide NSUserDefaults to achieve this. we can store any string,array etc into app preferences in the form of Key-Value using NSUserDefaults class.



So stay with me, and do it step by step by .. don't forget to drop me a message or comment.

At the end of this Tutorial you can find Complete Source code zip file.

Before starting You may like to know our preferences details

-----------------------------------------------
| Preferences Key  : Message_Text       |
| Key Value Type   : NSString       |
-----------------------------------------------

PHASE - I (Create New Project)

So, Let's Fire Xcode!!

Go to File --> New --> Project

Now we can see a Pop up Window for selecting our application templet 

So make sure you Single View Application templet as shown in below picture and Go for Next..



In the Next Window we need to put Our Project Details this way

 ---------------------------------------------------------------
| Product Name : NSUserDefaultsDemo       |
| Organization Name :RDCWorld         |
| Company Identifier : com.rdcworld          |
|                                 |
| Class Prefix :  (leave it blank for now)         |
|                                 |
| Devices : iPhone                         |
 ----------------------------------------------------------------

Note : Don't forget to Make Tick mark on "Use Automatic Reference Counting" option to enable ARC.



Go to Next --> Create.

Now you can see Xcode default dashboard with our newly created project .

PHASE - II (Add more ViewControllers)

we need to Add one more UIViewController for second screen. create and give name as "NextViewController" this way

1. File --> New --> File --> Select Objective -C class templet (in Cocoa Touch option).

2. In the next window give file details

Class : NextViewController
Subclass of : UIViewController

Select "With XIB for user interface" option --> Next -->create. 

So for now our application project structure look like



PHASE - III (Design UI)

Open ViewController.xib file

1. drag UIButton from object library and double click on it, update name as "Next" --> save this file

2. change background color to Green

Now open NextViewController.xib

4. drag one UILabel and double click on it, change value to "We go the message is :"

5. again drag one more UILabel on center of Layout double click and change name "result message".

6. change background color to Blue



PHASE - IV (Create IBOutlets and IBAction )

We are going to create IBAction methods for UIButton .

So just open ViewController.xib 

Okay, Now select Assistant Editor on Top Right side



You can see our ViewController.xib (Left side) + ViewController.h (Right side) opened together.

Create IBAction

3.  select Next Button -- > press Ctrl +Click and drag cursor  between @interface and @end  (in Right side Header File). 

4. in the pop up window make sure you change Connection type Outlet to --> Action, and give method name as "goToNextView"



you will find one IBAction method is created in header file and empty body is added in implementation file (.m file ) too

- (IBAction)goToNextView:(id)sender;


Create IBOutlet

open NextViewController.xib 

1. select Label (name is "result message")-- > press Ctrl +Click and drag cursor  between @interface and @end  (in Right side Header File). 

2. in the pop up window, put name as "receivedMessageLabel" and connect.
you will find one IBOutlet property is created in header file

@property (weak, nonatomic) IBOutlet UILabel *receivedMessageLabel;

Done!! now back to Standard Editor




PHASE - V (Writing Code)

~ ~ ~ ~ ~ ~ ~ ~ ~              Application Delegate Class (AppDelegate)          ~ ~ ~ ~ ~ ~ ~ ~ ~  

To enable Navigation Controller in our application we need to add it in app delegate.

So open AppDelegate.h

1.  create UINavigationController with property 

@property (strong, nonatomic) UINavigationController *rootController;

So Finally our AppDelegate.h file look like 

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  AppDelegate.h
//  NSDefaultUserDemo
//
//  Created by RDC on 3/11/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import <UIKit/UIKit.h>

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ViewController *viewController;
@property (strong, nonatomic) UINavigationController *rootController;

@end
-----------------------------------------------------------------------------------------------------------------------------------------

Now come to AppDelegate.m file 

2. in didFinishLaunchingWithOptions method initialize Navigation Controller, by adding ViewController as a Root.

self.rootController = [[UINavigationController alloc] initWithRootViewController:self.viewController];

3. add navigation controller to UIWindow

self.window.rootViewController = self.rootController;

Finally our AppDelegate.m file look like 

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  AppDelegate.m
//  NSDefaultUserDemo
//
//  Created by RDC on 3/11/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import "AppDelegate.h"
#import "ViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];   
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];    
    self.rootController = [[UINavigationController alloc] initWithRootViewController:self.viewController];    
    self.window.rootViewController = self.rootController;
    [self.window makeKeyAndVisible];
    return YES;
}

//for now leave rest all empty methods..

@end
-----------------------------------------------------------------------------------------------------------------------------------------


~ ~ ~ ~ ~ ~ ~ ~ ~              Controller Class (ViewController)           ~ ~ ~ ~ ~ ~ ~ ~ ~   

Open ViewController.h file

1. add @class statement just below to #import 

@class NextViewController;

2. create strong property for NextViewController, We are going to load via Next Button

@property (nonatomic, strong) NextViewController *nextViewController;

So Finally our ViewController.h file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.h
//  NavigationDemo
//
//  Created by RDC on 3/12/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import <UIKit/UIKit.h>

@class NextViewController;

@interface ViewController : UIViewController

@property (nonatomic, strong) NextViewController *nextViewController;

- (IBAction)goToNextView:(id)sender;

@end
-----------------------------------------------------------------------------------------------------------------------------------------

now open ContactObject's implementation class ViewController.m

1.  add synthesize (for all declared variable in header file with @property) just below to @implementation

@synthesize nextViewController;
@synthesize messageTextField;

2. in viewDidLoad method put title for Current view

 self.title = @"NSUserDefaults Demo";

3. Now Here is application's Heart, update goToNextView method body this way

 -:- To Store Data in Preferences -:-

- (IBAction)goToNextScreen:(id)sender {  
    
    NSString *messageString = messageTextField.text;
    
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    //save message into preferences 
    [prefs setObject:messageString forKey:@"MessageText"];    
    
    nextViewController = [[NextViewController alloc] init];
    [self.navigationController pushViewController:nextViewController animated:YES];
}

That's it, Save file.

So Finally our ViewController.m file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.m
//  NSDefaultUserDemo
//
//  Created by RDC on 3/11/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import "ViewController.h"
#import "NextViewController.h"

@interface ViewController ()
@end

@implementation ViewController
@synthesize nextViewController;
@synthesize messageTextField;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"NSUserDefaults Demo";
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];    
}

- (IBAction)goToNextScreen:(id)sender {  
    
    NSString *messageString = messageTextField.text;
    
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    //save message into preferences 
    [prefs setObject:messageString forKey:@"MessageText"];    
    
    nextViewController = [[NextViewController alloc] init];
    [self.navigationController pushViewController:nextViewController animated:YES];
}
@end
-----------------------------------------------------------------------------------------------------------------------------------------

~ ~ ~ ~ ~ ~ ~ ~ ~              Controller Class (NextViewController)           ~ ~ ~ ~ ~ ~ ~ ~ ~  

Make sure we already added one IBOutlet for UILabel in NextViewController.h file 

So Finally our NextViewController.h file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  NextViewController.h
//  NSDefaultUserDemo
//
//  Created by RDC on 3/12/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface NextViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *receivedMessageLabel;

@end
-----------------------------------------------------------------------------------------------------------------------------------------

now open its implementation file (NextViewController.m) file 

1. in viewDidLoad method update its Title 

self.title = @"Result Screen";

2. and get back the data from preferences

 -:- To Get Data from Preferences -:-

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    //get the message from preferences
    NSString *messageStr = [prefs stringForKey:@"MessageText"];

Note : make sure your key must be same as you defined while storing info

3. then show on label

receivedMessageLabel.text = messageStr;

So Finally our NextViewController.m file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  NextViewController.m
//  NSDefaultUserDemo
//
//  Created by RDC on 3/12/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import "NextViewController.h"

@interface NextViewController ()
@end

@implementation NextViewController
@synthesize receivedMessageLabel;


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.title = @"Result Screen";
    
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    //get the message from preferences
    NSString *messageStr = [prefs stringForKey:@"MessageText"];
    
    //Note : make sure your key must be same as you defined while storing info
    
    receivedMessageLabel.text = messageStr;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];    
}

@end
-----------------------------------------------------------------------------------------------------------------------------------------

Okay wrap it up this application. let's Run it --> enter any message



press Next button and you can see the message stored and we get it back.



Great!! we did it.

You can find complete project source code zip file here : NSDefaultUserDemo.zip (82.63 KB)

I Would love to here your thoughts !!