13

In iOS 7, developers are encouraged to show date pickers between table cells when needed for input, and then hide them when done. How can I achieve this effect?

enter image description here

ntaj
  • 311
  • 2
  • 21
danielmhanover
  • 3,094
  • 4
  • 35
  • 51
  • 1
    there is an answer to your question here: http://stackoverflow.com/questions/17646351/make-uipickerview-appear-between-cells-when-touched-cell – Lui Cruz Oct 03 '13 at 15:49

1 Answers1

16

Vasilica Costescu has a great tutorial on it here: http://masteringios.com/blog/2013/10/31/ios-7-in-line-uidatepicker/

And for static tables: http://masteringios.com/blog/2013/11/18/ios-7-in-line-uidatepicker-part-2/

Sample code here: https://github.com/costescv/InlineDatePicker

The key bits are the hide/show methods:

 - (void)showDatePickerCell {
    self.datePickerIsShowing = YES;
    [self.tableView beginUpdates];
    [self.tableView endUpdates];

    self.datePicker.hidden = NO;
    self.datePicker.alpha = 0.0f;

    [UIView animateWithDuration:0.25 animations:^{
        self.datePicker.alpha = 1.0f;
    }];
}

- (void)hideDatePickerCell {
    self.datePickerIsShowing = NO;
    [self.tableView beginUpdates];
    [self.tableView endUpdates];

    [UIView animateWithDuration:0.25
                     animations:^{
                         self.datePicker.alpha = 0.0f;
                     }
                     completion:^(BOOL finished){
                         self.datePicker.hidden = YES;
                     }];
}

And this UITableViewDelegate method will "hide" the row by setting its height to 0 :

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    if (indexPath.section == 0 && indexPath.row == 4 && self.datePickerIsShowing == NO){
        // hide date picker row
        return 0.0f;
    }
    return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}

You can call the hide/show methods from a button or just by selecting rows in the table. (Note: If there are text fields the other rows, then you may need to hide the datePicker in the textFieldDidBeginEditing delegate method).

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 && indexPath.row == 4) {
        if (self.datePickerIsShowing){
            [self hideDatePickerCell];
        }else {
            [self showDatePickerCell];
        }
    }
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}

EDIT: Be careful using more than a couple of these inline picker views on in a single table. I've noticed that they tend to load very slowly from storyboards: iOS 7 slow to open UITableViewController with UIPickerView

Community
  • 1
  • 1
Anthony F
  • 6,096
  • 4
  • 31
  • 32
  • @Antony F Do you have experience with this code and multiple Sections?! – davidOhara Jun 05 '14 at 09:57
  • @chrizstone - Yes. In my example there is only one datepicker at row 4 of section 0, but you can add multiple date pickers in different rows or sections. – Anthony F Jun 09 '14 at 21:14
  • I tried that, but for some reason sometimes a wrong picker is shown in the wrong row... – davidOhara Jun 10 '14 at 13:11
  • @chrizstone - Are you adding/removing the picker views from the table row? It's hard to guess the problem without seeing code, so you may want to post another question. I had to dynamically create the pickers when I had more than 3 in a storyboard view (too slow to load), but once each was created I left them in the row. Also, since it was confusing to the user to have more than one picker active at a time I ended up adding a NSIndexPath property to keep track of the active one. – Anthony F Jun 12 '14 at 19:45