【问题标题】:App crashes on call to 'tableView endUpdates'调用“tableView endUpdates”时应用程序崩溃
【发布时间】:2015-04-17 04:37:48
【问题描述】:

我目前正在 UITableViewCell 内实现inline UIDate picker

当我选择应该插入该单元格的正上方的单元格时,我能够显示和隐藏该选择器单元格,这是我所期望的行为。但是,如果我在表格视图中选择任何其他单元格,应用程序就会崩溃:

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

查看accepted answer to this SO question后,我添加了一个异常断点,我发现应用在调用didSelectRowAtIndexPath中的[tableView endUpdates];时崩溃了:

- (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]; 987654328注释呼叫时,则应用程序不会在选择其他单元格时崩溃,但是具有选择器视图的单元格将不会隐藏。有没有人有什么建议?谢谢!

编辑:下面是showTimePickerhideTimePicker 的代码:

- (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:阅读this SO thread后,我相信问题可能出在我的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;
    }
}

【问题讨论】:

  • 您能发布您的显示/隐藏 TimePicker 方法的代码吗?看看你如何显示时间选择器会很有帮助
  • 是的,当然,我很抱歉!
  • 请显示崩溃日志。另外,添加一个异常断点以显示它崩溃的位置。
  • 嗨@Fogmeister,谢谢,我会发布崩溃日志。我确实添加了一个异常断点;我将编辑我的问题以使其更清楚。

标签: ios objective-c uitableview didselectrowatindexpath


【解决方案1】:

不确定这是否是崩溃的根源,但不建议您多次调用 beginUpdates,就像您在
[tableView beginUpdates]; [self showTimePicker]; [tableView endUpdates]; 因为 showTimePicker 调用了[self.tableView beginUpdates];

【讨论】:

  • 谢谢你,Kim,我刚刚在 'didSelectRowAtIndexPath' 中取消了存在和结束更新的调用,但这次崩溃发生在调用 '[tableView endUpdates];' 时在“隐藏时间选择器”中
  • 只是为了确定:您是否在 didSelectRowAtIndexPath 中取消了所有对 begin/endUpdates 的调用?还有[self hideTimePicker];附近的那些?
  • 是的,我在 didSelectRowAtIndexPath 中取出了所有对 begin/endUpdates 的调用。这些调用存在的唯一地方是我的 show/hideTimePicker 方法。
  • 你能发布抛出的异常吗?
  • 好像是这样的:*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:1582
【解决方案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];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多