0

我正在使用我认为将项目添加到表格视图的常见模式 -

  • 主控制器创建模态控制器并将自己注册为委托
  • 模态视图控制器出现
  • 用户提供一些数据并点击模态导航栏中的保存按钮
  • 模态视图控制器向其委托发送一条消息,其中包含输入的详细信息
  • 原始控制器接收消息并关闭模态
  • 原始控制器更新数据模型并在其 tableview 中插入新行

除了在一种特定情况下,这运行良好。

如果在显示模式时旋转设备,应用程序会在关闭模式后崩溃。新行已正确插入,但随后立即失败:

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], 

/SourceCache/UIKit_Sim/UIKit-2380.17/UITableView.m:1070
2013-07-28 17:28:36.404 NoHitterAlerts[36541:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (8) must be equal to the number of rows contained in that section before the update (8), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

我一生都无法弄清楚为什么会发生这种情况。如果我使用呈现的模态进行旋转,则始终有效的测试用例会失败。我注意到只需重新加载 tableview 而不是插入带有动画的行就可以了。

这是一个演示相同问题的简单项目: demo project

  1. 在 iPhone sim 中运行项目
  2. 将项目添加到列表中 - 工作正常
  3. 返回第一个屏幕,旋转到横向
  4. 再次运行相同的测试。仍然有效。
  5. 返回第一个屏幕,启动模式。在模态仍然存在时旋转模拟器。点击“添加项目”。崩溃。

关于这里可能发生的事情有什么想法吗?

4

1 回答 1

1

我明白你的问题是什么。在 MainController 的-modalController:didAddItem:方法中,您首先将对象添加到,并且在方法完成self.arrayOfStrings之前不将行插入到 tableView中。-dismissViewControllerAnimated

当 modalViewController 打开时方向未更改时,这似乎有效,但是如果您确实更改了方向,则 mainController 的方向在关闭之前不会更改。一旦发生这种情况,似乎 tableView 的数据会由于框架被更改而自动重新加载。

因此,因为 arrayOfStrings 在动画开始之前添加了对象,并且-insertRowsAtIndexPaths:withRowAnimation:直到动画完成后才调用它,所以 table view 认为它在到达 insert 方法时已经获取了行。

为了解决这个问题,您所要做的就是在您调用 tableView 上的 insertRows 方法之前,将用于将字符串添加到数组中的方法移动到完成块中。

所以你的方法最终看起来像下面这样,你需要为你的实际项目做任何改变:

- (void)modalController:(ModalController *)controller didAddItem:(NSString *)string
{

    //dismiss the modal and add a row at the correct location
    [self dismissViewControllerAnimated:YES completion:^{
        [self.arrayOfStrings addObject:string];     
        [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:self.arrayOfStrings.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];

    }]; 
}
于 2013-07-29T02:06:33.263 回答