In previous versions of iOS the pickers were usually displayed in modal views.
But for iOS 7 Apple recommends the implementation in their iOS Human Interface Guidelines as follows:
"As much as possible, display a date picker inline with the content."
They also provide a sample implementation, but for tables with dynamic prototype cells what makes the implementation more complex.
Instead of deleting and inserting a row containing the picker, constantly modifying the data source, calculating the number of rows in the sections, etc. my solution for one cell using the date picker is:
- Store the picker's row height
- Store the picker's row's index path
- Set the picker's row height to 0 in viewDidLoad
- Set a flag reflecting the visibility of the picker to false
- When the date cell will be selected in tableView:didSelectRowAtIndexPath:, then negate the flag
- Depending on the flag's value set the height of the picker's cell either to 0, or to the original value
- Deselect the date's row in a [self.tableView beginUpdates] … [self.tableView endUpdates] block what causes the picker's cell to collapse and expand in an animated way.
The synchronization of the date cell's label text and the picker's value is trivial to solve and isn't subject of this post.
In case the date picker needs to be "attached" to several date cells, then the following need to be considered
- Use an array where the indexes represent the sections and the values the number of rows in the sections
- Use tableView:moveRowAtIndexPath:toIndexPath: (probably in a separate beginUpdates - endUpdates block)
- Reduce the number of rows in the source and increase the number of rows in the destination section by one (or do nothing if they are the same)
- Use the section's index for the array's index in tableView:numberOfRowsInSection:.