iOS remindersとかcalendarみたいな日付選択

iOSやるやる言いつつ、本読んでちょっと試して放置して2年ぐらい経つ気がするけど、先月ちょっと作ろうと思うものがあって始めた。

remindersとかcalendarみたいな日付選択を作りたくなって試してみた。

  • _datePickerCell, _dateFieldCellってクラス作ってnilと紐付ける。
  • _dateFieldCellを押した時に、_datePickerCell_cellsになかったら追加し、あれば削除
  • _datePickerCell編集開始時に_dateFieldCellの色を編集中の色にする、終れば確定の色にする。
  • _datePickerCellの値が変った時に_dateFieldCellの値を変える。

みたいなことをやった。(実際のコードから流れを簡易化するためにsectionを1個にしたり適当に手を加えた)

- (void)viewDidLoad
{
    // initialize _dateFieldCell, _datePickerCell
    // ...
    _cells = @{
        // ...
        _dateFieldCell
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self cellForIndexPath:indexPath] == _datePickerCell) {
        return _datePickerCell.picker.frame.size.height;
    }

    return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [_cells count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [_cells indexPath.row];
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *selectedCell = [self cellForIndexPath:indexPath];

    if (selectedCell == _dateFieldCell) {
        [self toggleDatePickerCell];
    } else {
        // ...
    }

    [self closeSoftKeyboard];
}

- (void)toggleDatePickerCell
{
    if ([_cells containsObject:_datePickerCell]) {
        [self _hideDatePickerCell];
    } else {
        [self _showDatePickerCell];
    }
}

- (void)_showDatePickerCell
{
    int targetIndex = [NSIndexPath indexPathForRow:[_cells indexOfObject:_dateFieldCell] + 1;

    [self.tableView beginUpdates];
    [_cells insertObject:_datePickerCell atIndex:targetIndex];
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:targetIndex inSection:0]]
                          withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView endUpdates];

    // 日付を編集中の色にしたり
    [_dateFieldCell didStartEditing];
}

- (void)_hideDatePickerCell
{
    int targetIndex = [NSIndexPath indexPathForRow:[_cells indexOfObject:_dateFieldCell] + 1;

    [self.tableView beginUpdates];
    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:targetIndex inSection:0]]
                          withRowAnimation:UITableViewRowAnimationFade];
    [_cells removeObjectAtIndex:targetIndex];
    [self.tableView endUpdates];

    // 日付を確定の色にしたり
    [_dateFieldCell didEndEditing];
}

// DatePickerCell delegate(DatePickerCellが変更された時)
- (void)dateDidChange:(UIDatePicker *)datePicker
{
    _dateFieldCell.date = datePicker.date;
}

- (void)closeSoftKeyboard
{
    [self.tableView endEditing:YES];
}