Use Custom Input-Views(DatePicker, PickerView) And Toolbar In TextField

Firstly, you must have noticed that a keyboard appears when you click on any TextField/TextView. That keyboard is just a default Input View of Textfield or TextView.

We can change it with the help of UI Kit Framework.

Now lets get started,

  • Open Xcode.
  • Click on Create a new Xcode project.
  • Now select Single View Application.
  • Click -> Next.
  • Enter -> Product Name and Other blank fields (if any).
  • Now select the location where you want to save your project and click on Create.

Write/copy the following code in ViewController.h.

  1. #  
  2. import < UIKit / UIKit.h >  
  3.   
  4.     @interface ViewController: UIViewController   
  5.       
  6.     {  
  7.         UIDatePicker * DatePicker;  
  8.         UIPickerView * Picker;  
  9.         NSArray * CountryArray;  
  10.         NSArray * heightInch;  
  11.         NSArray * heightFeet;  
  12.     }  
  13.   
  14. @property(strong, nonatomic) IBOutlet UITextField * dateSelectionTextField;  
  15. @property(strong, nonatomic) IBOutlet UITextField * countryTextField;  
  16. @property(strong, nonatomic) IBOutlet UITextField * heightTextField;  
  17.   
  18.   
  19. @end 

Copy all in same sequence in ViewController.m

  1. #  
  2. import "ViewController.h"  
  3.   
  4. @interface ViewController() < UIPickerViewDataSource, UIPickerViewDelegate >  
  5.   
  6.     @end  
  7.   
  8. @implementation ViewController  
  9. @synthesize dateSelectionTextField, countryTextField, heightTextField;  
  10.   
  11.   
  12. - (void) viewDidLoad   
  13. {  
  14.   [super viewDidLoad];  
  15.   // Do any additional setup after loading the view, typically from a nib. 

Now firstly we are going to allocate DatePicker and set input of dateSelectionTextField to DatePicker.

  1. //For DatePicker  
  2. DatePicker =  
  3. [  
  4.     [UIDatePicker alloc] init  
  5. ];  
  6. DatePicker.datePickerMode = UIDatePickerModeDate; //You can change Picker mode here  
  7. [self.dateSelectionTextField setInputView: DatePicker]; 

Same for Picker but with some custom colour changes.

  1. //For Picker  
  2. Picker =   
  3. [  
  4.     [UIPickerView alloc] init  
  5. ];  
  6. Picker.delegate = self;  
  7. Picker.dataSource = self;  
  8. [Picker setShowsSelectionIndicator: YES];  
  9. Picker.tintColor = [UIColor blackColor];  
  10. Picker.backgroundColor = [UIColor colorWithRed: 153.0 green: 204.0 blue: 255.0 alpha: 2]; 

These Arrays holds the values of content in Picker.

  1. //Arrays  
  2. CountryArray =   
  3. [  
  4.     [NSArray alloc] initWithObjects: @ "USA", @ "India", @ "France", nil  
  5. ];  
  6. heightFeet =   
  7. [  
  8.     [NSArray alloc] initWithObjects: @ "3", @ "4", @ "5", @ "6", @ "7", @ "8", nil  
  9. ];  
  10. heightInch =   
  11. [  
  12.     [NSArray alloc] initWithObjects: @ "0", @ "1", @ "2", @ "3", @ "4", @ "5", @ "6", @ "7", @ "8", @ "9", @ "10", @ "11", nil  
  13. ]; 

This is to set InputView of TextField.

Note: One Picker allocation can be used for multiple text fields.

  1. //ForPicker  
  2. [self.countryTextField setInputView: Picker];  
  3. [self.heightTextField setInputView: Picker]; 

Now will make a Toolbar which will provide ease to user to go to another textfields.

  1. //For ToolBar  
  2. UIToolbar * toolBar =   
  3. [  
  4.     [UIToolbar alloc] initWithFrame: CGRectMake(0, 0, 320, 45)  
  5. ];  
  6. [toolBar setTintColor: [UIColor blueColor]];  
  7. UIBarButtonItem * doneBtn =   
  8. [  
  9.     [UIBarButtonItem alloc] initWithTitle: @ "Done"  
  10.     style: UIBarButtonItemStyleDone target: self action: @selector(Done)  
  11. ];  
  12. UIBarButtonItem * space =   
  13. [  
  14.     [UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace target: nil action: nil  
  15. ];  
  16. UIBarButtonItem * prevBtn =   
  17. [  
  18.     [UIBarButtonItem alloc] initWithImage: [UIImage imageNamed: @ "765-arrow-left.png"] style: UIBarButtonItemStylePlain target: self action: @selector(previous)  
  19. ];  
  20. UIBarButtonItem * nextBtn = [  
  21.     [UIBarButtonItem alloc] initWithImage: [UIImage imageNamed: @ "766-arrow-right.png"] style: UIBarButtonItemStylePlain target: self action: @selector(next)  
  22. ];  
  23.   
  24. prevBtn.width = 20.0;  
  25. nextBtn.width = 70.0;  
  26.   
  27. [toolBar setItems: [NSArray arrayWithObjects: prevBtn, nextBtn, space, doneBtn, nil]]; 

Now this will add the toolbar to textfields.

  1. //for date textfield  
  2. [self.dateSelectionTextField setInputAccessoryView: toolBar];  
  3.   
  4. //for country textfield  
  5. [self.countryTextField setInputAccessoryView: toolBar];  
  6.   
  7. //for Height textfield  
  8. [self.heightTextField setInputAccessoryView: toolBar];  

This gives Action to Done button on toolbar.

  1. //For Date picker  
  2. -(void) Done   
  3. {  
  4.     //for date picker only  
  5.     NSDateFormatter * formatter =   
  6.     [  
  7.         [NSDateFormatter alloc] init  
  8.     ];  
  9.     [formatter setDateFormat: @ "dd/MMM/YYYY"];  
  10.     self.dateSelectionTextField.text = [NSString stringWithFormat: @ "%@", [formatter stringFromDate: DatePicker.date]];  
  11.     [self.dateSelectionTextField resignFirstResponder];  
  12.   
  13.     //forPicker  
  14.     [self.countryTextField resignFirstResponder];  
  15.     [self.heightTextField resignFirstResponder];  

Now these are the required method for PickerView.

  1. //For Picker  
  2. -(NSInteger) numberOfComponentsInPickerView: (UIPickerView * ) pickerView   
  3. {  
  4.     if ([countryTextField isFirstResponder])   
  5.     {  
  6.   
  7.         return 1;  
  8.     } else if ([heightTextField isFirstResponder])   
  9.     {  
  10.   
  11.         return 2;  
  12.     } else  
  13.         return 1;  
  14. }  
  15.   
  16. - (NSInteger) pickerView: (UIPickerView * ) pickerView numberOfRowsInComponent: (NSInteger) component   
  17. {  
  18.     if ([countryTextField isFirstResponder])   
  19.     {  
  20.   
  21.         return [CountryArray count];  
  22.   
  23.     } else if ([heightTextField isFirstResponder])   
  24.     {  
  25.   
  26.         if (component == 0)   
  27.         {  
  28.             return [heightFeet count];  
  29.         } else {  
  30.             return [heightInch count];  
  31.         }  
  32.     }  
  33.     return 1;  
  34. }  
  35.   
  36. - (NSString * ) pickerView: (UIPickerView * ) pickerView titleForRow: (NSInteger) row forComponent: (NSInteger) component {  
  37.     if ([countryTextField isFirstResponder])   
  38.     {  
  39.         return [CountryArray objectAtIndex: row];  
  40.   
  41.     } else if ([heightTextField isFirstResponder])   
  42.     {  
  43.         if (component == 0)   
  44.         {  
  45.   
  46.             return [heightFeet objectAtIndex: row];  
  47.         } else   
  48.         {  
  49.             return [heightInch objectAtIndex: row];  
  50.         }  
  51.     }  
  52.   
  53.     return 0;  
  54. }  
  55.   
  56. - (void) pickerView: (UIPickerView * ) pickerView didSelectRow: (NSInteger) row inComponent: (NSInteger) component   
  57. {  
  58.   
  59.     if ([countryTextField isFirstResponder])   
  60.     {  
  61.         self.countryTextField.text = [CountryArray objectAtIndex: row];  
  62.     } else if ([heightTextField isFirstResponder])   
  63.     {  
  64.   
  65.         [heightTextField setText: [NSString stringWithFormat: @ "%@' %@''", [heightFeet objectAtIndex: [Picker selectedRowInComponent: 0]],  
  66.             [heightInch objectAtIndex: [Picker selectedRowInComponent: 1]]  
  67.         ]];  
  68.     }  
  69.   

You may have a question that why these if-else statements are used?.

So the answer is, they are providing different values and different Textfields via Same Picker.

Now lets go ahead, the following coding is providing action to previous and next buttons on toolbar.

  1. -(void) previous {  
  2.     if ([countryTextField isFirstResponder])   
  3.     {  
  4.   
  5.         [self.countryTextField resignFirstResponder];  
  6.         [dateSelectionTextField becomeFirstResponder];  
  7.     } else if ([heightTextField isFirstResponder])   
  8.     {  
  9.   
  10.         [self.heightTextField resignFirstResponder];  
  11.         [countryTextField becomeFirstResponder];  
  12.     }  
  13.   
  14. }  
  15.   
  16. - (void) next   
  17. {  
  18.     if ([dateSelectionTextField isFirstResponder])   
  19.     {  
  20.         NSDateFormatter * formatter =   
  21.         [  
  22.             [NSDateFormatter alloc] init  
  23.         ];  
  24.         [formatter setDateFormat: @ "dd/MMM/YYYY"];  
  25.         self.dateSelectionTextField.text = [NSString stringWithFormat: @ "%@", [formatter stringFromDate: DatePicker.date]];  
  26.   
  27.         [self.dateSelectionTextField resignFirstResponder];  
  28.         [countryTextField becomeFirstResponder];  
  29.   
  30.     } else if ([countryTextField isFirstResponder])   
  31.     {  
  32.         [self.countryTextField resignFirstResponder];  
  33.         [heightTextField becomeFirstResponder];  
  34.   
  35.     }  

This is an important method which prevents the values of different textfields from mixing up.

  1. -(void) textFieldDidBeginEditing: (UITextField * ) textField   
  2. {  
  3.     [Picker reloadAllComponents];  
  4. }  
  5.   
  6. - (void) didReceiveMemoryWarning   
  7. {  
  8.     [super didReceiveMemoryWarning];  
  9.     // Dispose of any resources that can be recreated.  
  10. }  
  11. @end 

ALL DONE IN CODING PART

Open Main.storyboard

  1. Drag a TextField in ViewController and resize it.
  2. You can change its Alignment to Centre.
  3. Set new Referencing Outlet named “dateSelectionTextField” and delegate.
  4. In same way add two more textfields.
  5. Set Properties and delegates there.

Now take a deep breath and run your Project.

Your storyboard will look like the following screenshot,

Storyboard

Date Formats

@"dd/mm/yyyy" for 20/08/2015.
@"dd/MMM/YYYY" for 22/Nov/2015.
@"dd/MMM/YYYY hh:min a” for 19/Nov/2015 03:10