UITableView的reloadRowsAtIndexPaths:似乎打破了insertRowsAtIndexPaths:

时间:2012-04-01 05:59:30

标签: ios uitableview uikit

我有UITableView用户可以插入新行。发生这种情况时,我想重新加载表中的所有旧行。一种解决方案是在插入完成后立即调用reloadData,这完全有效,但这意味着我没有得到插入动画。

因此,当用户点击“添加行”按钮时,我会使用除刚刚插入的索引路径之外的每个索引路径调用reloadRowsAtIndexPaths:。然后我只用新插入的行调用insertRowsAtIndexPaths:。合理,对吧?

这会导致应用程序崩溃,并提供以下说明:

  

无效更新:第0节中的行数无效。更新(1)后现有部分中包含的行数必须等于更新前的该部分中包含的行数(0),或者减去从该部分插入或删除的行数(插入0,删除0)和加或减移入或移出该部分的行数(0移入,0移出)。

正如您在本示例中所看到的,即使reloadRowsAtIndexPaths传递了一个空的索引路径数组,也会发生这种情况。

啊!我需要用beginUpdatesendUpdates打包两个电话。很公平。但现在动画完全破碎了。

我正在使用UITableViewRowAnimationFade执行重新加载,并使用UITableViewRowAnimationAutomatic进行重新加载。但是在动画期间,每一行的高度都会发生变化,从而产生这种奇怪的闪烁效果,看起来很糟糕。动画这些变化的正确方法是什么?

编辑:

来自reloadRowsAtIndexPaths:withRowAnimation:的文档:

  

重新加载行会导致表视图向其数据源询问该行的新单元格。该表动画化了新单元格,因为它为旧行设置了动画。如果要提醒用户单元格的值正在更改,请调用此方法。但是,如果通知用户并不重要 - 也就是说,您只想更改单元格显示的值 - 您可以获取特定行的单元格并设置其新值。

我认为,在我的应用程序中,手动更新每个单元格是正确的方法。然而,我仍然对这个奇怪的动画错误感到不安,并想知道它的原因是什么/如果我做“想要警告用户细胞的价值正在发生变化的话我会怎么做。”

2 个答案:

答案 0 :(得分:4)

正如文档所说,获得该错误的一个常见原因是,数据源需要一个单元格。它可能不太清楚,它被要求两次......一次提供初始数据,再次提供最终数据。这意味着tableView:numberOfRowsInSection:方法必须返回beginUpdates之前的旧值和endUpdates之后的新值(或者如果您在调用之前和之后使用快捷方法)。如果相关,请不要忘记numberOfSectionsInTableView。

示例:

    numberOfRows... return [array count];

    // Incorrect
    [array addObject:object];
    [tableView beginUpdates];
    [tableView insertRow..];
    [tableView endUpdates];

    // Correct
    [tableView beginUpdates];
    [array addObject:object];
    [tableView insertRow..];
    [tableView endUpdates];

对于您的具体情况,我建议您进行插入,然后在整个tableview上调用reloadData,只要这不会弄乱您的动画或其他任何内容。

答案 1 :(得分:-2)

您不需要对完全单元格进行任何操作。您需要的只是 - 更改您的数据源数组,然后调用重新加载数据/行/部分,您将在表视图中更改数据,并添加行。