Приложение вылетает при вызове "tableView endUpdates"

В настоящее время я работаю над реализацией встроенного средства выбора UIDate внутри UITableViewCell.

Я могу показать и скрыть эту ячейку выбора, когда выбираю ячейку прямо над тем местом, где эта ячейка должна быть вставлена, и это то поведение, которое я ожидаю. Однако приложение вылетает, если я выбираю любые другие ячейки в табличном представлении:

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:1582

Посмотрев принятый ответ на этот вопрос SO, я добавил точку останова исключения, и я обнаружил, что приложение вызывает сбой при вызове [tableView endUpdates]; в didSelectRowAtIndexPath:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];

    // Check to see if the "Only Alert From" row was selected. The cell with the picker should be below this one.
    if (indexPath.section == TimeOfDaySection && indexPath.row == HourTimeZoneRow  && self.timePickerIsShowing == NO){

        [tableView beginUpdates];
        [self showTimePicker];
        [tableView endUpdates];

    } else{
        [tableView beginUpdates];
        [self hideTimePicker];
        [tableView endUpdates];
        [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
    }
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Тем не менее, я не уверен, как поступить. Если я закомментирую звонок [tableView endUpdates];приложение не будет зависать при выборе других ячеек, НО ячейка с видом средства выбора не будет скрыта. У кого-нибудь есть предложения? Спасибо!

РЕДАКТИРОВАТЬ: ниже мой код для showTimePicker а также hideTimePicker:

- (void)showTimePicker
{
    self.timePickerIsShowing = YES;
    self.timePicker.hidden = NO;

    //Create the index path where we insert the cell with the picker
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:HourTimeZoneRow + 1 inSection:TimeOfDaySection];

    [self.tableView beginUpdates];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView endUpdates];

    self.timePicker.alpha = 0.0f;
    [UIView animateWithDuration:0.25 animations:^{
        self.timePicker.alpha = 1.0f;
        //This is the row where the picker cell should be inserted
        [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:HourTimeZoneRow + 1 inSection:TimeOfDaySection]] withRowAnimation:UITableViewRowAnimationFade];
        [self.tableView reloadData];
    }];
}

- (void)hideTimePicker {
    self.timePickerIsShowing = NO;
    self.timePicker.hidden = YES;

    //Create the index path where we delete the cell with the picker
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:HourTimeZoneRow + 1 inSection:TimeOfDaySection];
    [self.tableView beginUpdates];
    //Delete the picker row
    [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView endUpdates];
    [UIView animateWithDuration:0.25
                     animations:^{
                         self.timePicker.alpha = 0.0f;
                     }
                     completion:^(BOOL finished){
                         self.timePicker.hidden = YES;
                     }];
}

РЕДАКТИРОВАТЬ 2: После прочтения этой темы я думаю, что проблема может быть с моим numberOfRowsInSection метод:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    switch (section) {
        case NotificationsSection:
            return TotalPreferencesRows;
            break;
        case RedZoneSection:
            return TotalRedZoneRows;
            break;
        case TimeOfDaySection:
            if (self.timePickerIsShowing) {
                return TotalTimeOfDayRows + 1;
            }
//            else if (self.timePickerIsShowing == NO){
//                return TotalTimeOfDayRows;
//            }
            else{
                return TotalTimeOfDayRows;
            }
            return TotalTimeOfDayRows;
            break;
        default:
            return 0;
            break;
    }
}

2 ответа

Решение

Проблема в вашем didSelectRowAtIndexPath, вы вызываете метод hide, даже если он может не отображаться. Сделать else пункт в else if, как это:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];

    // Check to see if the "Only Alert From" row was selected. The cell with the picker should be below this one.
    if (indexPath.section == TimeOfDaySection && indexPath.row == HourTimeZoneRow  && self.timePickerIsShowing == NO){

        [tableView beginUpdates];
        [self showTimePicker];
        [tableView endUpdates];

    } else if (indexPath.section == TimeOfDaySection && indexPath.row == HourTimeZoneRow  && self.timePickerIsShowing == YES){
        [tableView beginUpdates];
        [self hideTimePicker];
        [tableView endUpdates];
        [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
    }
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Не уверен, что это является причиной сбоя, но не рекомендуется вызывать beginUpdates несколько раз, что вы делаете в
[tableView beginUpdates]; [self showTimePicker]; [tableView endUpdates];потому что showTimePicker вызывает [self.tableView beginUpdates];

Другие вопросы по тегам