One of the new features in iOS 7 is the in-line UIDatePicker. You might have noticed in the Calendar app or in the Reminder app that when you want to select a date for your event, instead of seeing the UIDatePicker come up from the bottom of the screen like the keyboard, now you see it below the cell that contains the date. This is how it looks like in the Calendar app:
Today we are going to see how to replicate this behaviour. We are going to create a small project that will demonstrate how to display in-line date pickers in both dynamic and static UITableView cells. Our demo app will display a list of people represented by their name and their date of birth. When you select one person an in-line date picker will appear and allow you to change the date of birth. This is the implementation that will use the dynamic prototype cell. On the navigation bar there is a + button that allows you to add a new person. A modal screen will appear and it will allow you to enter the name of the person, its date of birth and the place of birth. This is where we will use static cells. The finished app will look like this:
Project setup
Let’s get started by going to File->New Project in Xcode and selecting the Master-Detail Application template.
Name your project InlineDatePicker. We’re not using Core Data so deselect that check box. Press Next when ready and on the next screen select where you want to store your project and then click Create. When you run the project you will see something like this:
You can tap the “+” button to create a new entry and then tap on the new row to see a detail view for it:
We already have a working project thanks to Xcode’s template and it is quite close to what we want. We have a table view and a detail view, all we need to do is customise them to suit our needs.
Table view setup
The template created the following file structure for us:
We are going to make VCMasterViewController display our list of people, so let’s start by giving it a more suitable name. Select VCMasterViewController.h file, then in that file right click on the name of the view controller and choose Refactor->Rename… The new name will be VCPeopleViewController.
How do you dismiss the date picker once you’re done with it?
To hide the date picker in the UI you just need to tap on the same cell that triggered the date picker to be shown. The method hideExistingPicker is the one that contains the code. All it does is to delete the row containing the date picker.
Pingback: iOS 7 inline UIDatePicker | Mastering iOS
Really nice. When I had done this in the past I used delegates between the tableview and cell which was a mess and violated all kinds of rules i’m sure. This is a much cleaner and easier approach, well done. Thanks for sharing!
Nice article, I managed to translate it to C# for use with Xamarin – I used a UITableView with a UITableViewSource set as source, implementing your example in the UITableViewSource.
When I implemented the methods hideExistingPicker, calculateIndexPathForNewPicker, and showNewPickerAtIndex in C#, I did it like this, passing tableView and indexPath to the methods:
private void HideExistingPicker(UITableView tableView, NSIndexPath selectedIndexPath )
{
// …
}
private void ShowNewPickerAtIndex(UITableView tableView, NSIndexPath indexPath)
{
// …
}
private NSIndexPath CalculateIndexPathForNewPicker(UITableView tableView, NSIndexPath selectedIndexPath)
{
// …
}
Also, if anyone needs it, the methods to override in UITableViewSource in C# are:
Objective C name C# name
– numberOfRowsInSection: public override int RowsInSection(UITableView tableview, int section)
– cellForRowAtIndexPath: public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
– didSelectRowAtIndexPath: public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
– heightForRowAtIndexPath: public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
Hi,
Do you have a working example of this using Xamarin anywhere where I can read a completed solution?
Thanks,
Hello
Do you have the same example bout implement UITableView and not implement of UITableViewController?
Hi,
Nice Tutorial..
But its crashes…
if you added more rows in table and click on any row, and scroll it …
its crash application…
Please help…
Hi,
Add this to the if clause in your cellForRowAtIndexPath:
} else if ([self datePickerIsShown] && indexPath.row > self.datePickerIndexPath.row) {
// after the picker cell we’ll have to decrement the index by 1
VCPerson *person = self.persons[indexPath.row – 1];
cell = [self createPersonCell:person];
} else {
VCPerson *person = self.persons[indexPath.row];
cell = [self createPersonCell:person];
}
Should work
Thanks, This is very helpful and actually fun to work thru your lead. Now I will tackle your part 2.
Thanks again !!!
Do you happen to know how to do this with a UIPickerView so that one can have a picker with minutes and seconds?
You should use a UIDatePicker for this and set the mode to UIDatePickerModeTime.