24

How can I display a datetimepicker control on tap of a textbox?

I have a user interface that has arrival and departure text fields, and when a user clicks on arrival textbox it should bring up a datetimepicker control up instead of a keyboard and the same with the departure textbox.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
appuser
  • 269
  • 1
  • 3
  • 10

5 Answers5

42

You can use inputView and inputAccessoryView properties of the text field for this. Create the date picker and set it to the input views of the two text fields. Also create another view for the Done button and it as their accessory view. You will need that button to dismiss the input view.

The Done button must be wired up to function which basically does this –

if ( [textField1 isFirstResponder] ) {
    [textField1 resignFirstResponder];
} else if ( [textField2 isFirstResponder] ) {
    [textField2 resignFirstResponder];
}

Another option would be to subclass UITextField and override inputView and inputAccessoryView. This is the way to go when there are loads of them.

Example

@interface CustomKeyboardAppDelegate : NSObject <UIApplicationDelegate> {
...

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITextField *textField;
@property (nonatomic, retain) IBOutlet UIToolbar *accessoryView;
@property (nonatomic, retain) IBOutlet UIDatePicker *customInput;

- (IBAction)dateChanged:(id)sender;
- (IBAction)doneEditing:(id)sender;
@end

In the XIB, Pull out a UIToolbar and a UIDatePicker but don't attach it to the view. Connect the outlets appropriately. dateChanged: responds to changes in the date picker and doneEditing: is called when the Done button in the tool bar is clicked. Connect them too. The methods are implemented as listed below.

@implementation CustomKeyboardAppDelegate

@synthesize window=_window;
@synthesize textField = _textField;
@synthesize accessoryView = _accessoryView;
@synthesize customInput = _customInput;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.textField.inputView = self.customInput;
    self.textField.inputAccessoryView = self.accessoryView;
    ...    
}

...

- (IBAction)dateChanged:(id)sender {
    UIDatePicker *picker = (UIDatePicker *)sender;

    self.textField.text = [NSString stringWithFormat:@"%@", picker.date];
}

- (IBAction)doneEditing:(id)sender {
    [self.textField resignFirstResponder];
}
@end

The last two methods will bloat up as more text fields depend on this picker.

Arkaaito
  • 7,347
  • 3
  • 39
  • 56
Deepak Danduprolu
  • 44,595
  • 12
  • 101
  • 105
  • Thanks for your answer.Can you please tell me how I will create a datepicker and set it to the input views? Is this something that I have to do in the Interface Builder or through code? – appuser May 20 '11 at 18:29
  • Added an example for a single text field. You can do this via IB as I have done. – Deepak Danduprolu May 20 '11 at 18:48
  • Thanks a lot for your help @Deepak.I really appreciate it. I also wanted to vote you up but unfortunately that requires 15 reputations:( – appuser May 20 '11 at 19:17
  • @Deepak how should the toolbar be set up? In my version of Xcode, the toolbar starts with a button on it ("Item"), and it's not linked to anything, and neither dateChanged or doneEditing are ever being called. –  Jun 09 '11 at 09:13
  • `Item` should be renamed to `Done` and then connected to `doneEditing:`. – Deepak Danduprolu Jun 09 '11 at 11:10
  • 2
    @Deepak what do you mean by "don't attach it to the view" ? I follow your code, that is working fine except for the DatePicker that is present on my view when the view appears. How can I hide it on startup ? Thanks a lot. – Luc Dec 16 '11 at 11:31
  • Thanks a lot, @Deepak. This has truly saved my day! – pxlshpr Jan 05 '12 at 08:24
11

Very simple, in ViewController.h put the UITextFieldDelegate after in viewDidLoad.

txtFecha.delegate = self;

datePicker = [[UIDatePicker alloc]init];
[datePicker setDatePickerMode:UIDatePickerModeDate];

self.txtFecha.inputView = datePicker;
ChrisWue
  • 18,612
  • 4
  • 58
  • 83
oscar castellon
  • 3,048
  • 30
  • 19
3

In viewDidLoad of ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];

    UIDatePicker *datePicker = [[UIDatePicker alloc]init];
    [datePicker setDate:[NSDate date]];
    datePicker.datePickerMode = UIDatePickerModeDate;
    [datePicker addTarget:self action:@selector(dateTextField:) forControlEvents:UIControlEventValueChanged];
    [txtFieldBranchYear setInputView:datePicker];
}

Add one method in your ViewController

-(void) dateTextField:(id)sender
{
    UIDatePicker *picker = (UIDatePicker*)txtFieldBranchYear.inputView;
    [picker setMaximumDate:[NSDate date]];
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    NSDate *eventDate = picker.date;
    [dateFormat setDateFormat:@"dd/MM/yyyy"];

    NSString *dateString = [dateFormat stringFromDate:eventDate];
    txtFieldBranchYear.text = [NSString stringWithFormat:@"%@",dateString];
}

txtFieldBranchYear is an outlet of UITextField

iAnkit
  • 1,940
  • 19
  • 25
  • This is the right solution for me. Works with 8.2. However I'd probably remove: [picker setMaximumDate:[NSDate date]]; to prevent confusion. – Aku Jan 30 '15 at 03:50
1

There's a really useful class I found - the blog post is here: http://www.pietrorea.com/2012/07/how-to-hide-the-cursor-in-a-uitextfield/ but it basically uses the inputView/inputAccessory view as well. The kicker is that the UILabel, at least for what I was doing, was exactly what I needed.

chug2k
  • 5,106
  • 2
  • 25
  • 30
0

open date picker on click on textField swift 3.0 add UITextFieldDelegate and set delegate on ViewDidload() tfDate.delegate = self

//MARK:- TextField Delegate
//MARK:-

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

//MARK:- DatePicker
//MARK:-

func textFieldDidBeginEditing(_ textField: UITextField) {
     self.callDatePicker(textField: tfDate)
}
func callDatePicker(textField:UITextField){
    let datePickerView  : UIDatePicker = UIDatePicker()
    datePickerView.datePickerMode = UIDatePickerMode.date
    textField.inputView = datePickerView
    datePickerView.addTarget(self, action: #selector(MyViewController.handleDatePicker), for: .valueChanged)
}

var str:String = ""
var str1:String = ""
var strStartDate:Date!
var strEndDate:Date!

func handleDatePicker(sender: UIDatePicker) {

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "dd-MM-yyyy"
    print("Date :: \(dateFormatter.string(from: sender.date))")
    tfDate.text = dateFormatter.string(from: sender.date)


}
Maulik Patel
  • 2,045
  • 17
  • 24