How to show uidatepicker from uitableviewcell

cocoa-touch, ios, objective-c

Solution

I've recently just had to do the exact same thing.

- Insert a `UITextField` into your `UITableViewCell` (you may need to create a custom `UITableViewCell` depending whether you want it to appear on every dynamic cell of your `UITableView` or on a single static cell).

Create properties for a `UIDatePicker`, a `UIToolbar`, and a `UITextField`, then in IB hook up the `UITextField` property to your `UITextField` created in Step 1 (If you're using a custom `UITableViewCell` class, that's where the `UITextField` property would need to go):

@property (strong, nonatomic) UIDatePicker * datePicker;
@property (strong, nonatomic) UIToolbar * datePickerToolbar;
@property (strong, nonatomic) IBOutlet UITextField *textField;

...

@synthesize datePicker, datePickerToolbar, textField;

Setup your `UIDatePicker`, `UIToolbar`, and `UITextField`:

- (void)viewDidLoad {
    // Initialise UIDatePicker
    datePicker = [[UIDatePicker alloc] init];
    datePicker.datePickerMode = UIDatePickerModeTime;
    [datePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged]; // method to respond to changes in the picker value

    // Setup UIToolbar for UIDatePicker
    datePickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
    [datePickerToolbar setBarStyle:UIBarStyleBlackTranslucent];    
    UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(dismissPicker:)]; // method to dismiss the picker when the "Done" button is pressed    
    [datePickerToolbar setItems:[[NSArray alloc] initWithObjects: extraSpace, doneButton, nil]];


    // Note: If you're using dynamic cells, the below 2 lines need to be in your cellForRowAtIndexPath method instead.

    // Set UITextfield's inputView as UIDatePicker    
    textField.inputView = datePicker;
    // Set UITextfield's inputAccessoryView as UIToolbar
    textField.inputAccessoryView = datePickerToolbar;
}

Setup `dismissPicker` method:

-(void)dismissPicker:(id)sender{
    [textField resignFirstResponder];
}

Setup `datePickerValueChanged` method:

- (void)datePickerValueChanged:(id)sender{
    NSDate *selectedDate = datePicker.date;

    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    [df setDateFormat:@"HH:mm"]; 

    [textField setText:[df stringFromDate:selectedDate]];
}

Note: In my code, I needed the interface to display the time, hence the date format set here (`HH:mm`). Because of this, you will also notice that in my `UIDatePicker` initialization code in `viewDidLoad`, I've set its mode to `UIDatePickerModeTime`. For date selections, you may want to set it to `UIDatePickerModeDate`.

Problem

How can I show a `UIDatePicker` from UITableViewCell, and have the `datepicker` have a toolbar at the top that lefts you resign it? Are there any good tutorials on how to do this?

Original source