TableView reloadData与beginUpdates& endUpdates

时间:2011-11-17 20:42:27

标签: ios objective-c reloaddata

我有一个关于更新我的TableView的棘手问题,我使用不同的更新方法得到不同的结果,让我解释一下:

情况1: 我使用[tbl reloadData]; tbl是我的TableView,来更新TableView - 按预期工作。

情况2: 我用:

[tbl beginUpdates];
[tbl reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationRight];
[tbl endUpdates];

tbl是我的TableView,而indexPaths是一个包含TableView中存在的所有indexPath的数组。现在数组很好,它包含所有正确的indexPaths(双重和三重检查)但由于某种原因 - 这不能按预期工作。

现在我意识到这是一个XY问题(我问Y但我的问题确实是X因为我认为解决Y会解决X)而这只是因为我觉得解释X有点复杂(后果是上面的问题)以一种简单的方式,所以如果可能的话我宁愿避免这样做。

所以,直到我的问题:更新TableView的两种方式之间是否存在差异(当然除了动画位)或者我是否应该怀疑问题要放在其他地方?

修改 好的,我会尝试解释症状是什么:

cellForRowAtIndexPath - 方法中,我为每个单元格添加一个按钮,其中指定的标签等于单元格的indexPath行,如下所示:

btn.tag = indexPath.row;

我这样做的原因是我可以识别每个按钮,因为它们都调用相同的功能:

- (void)btnPressed:(id)sender

然后我更新单元格 - 因为单元格中的某些值已经改变 - 情境1使一切正常,情况2然而 - 混合标签,以便下次按下其中一个按钮时,它们不再具有正确的标签。

混音对我来说确实是随机的,但随机化的发生方式不同,这取决于我先按哪个单元格按钮。我希望这能澄清我的问题。

3 个答案:

答案 0 :(得分:21)

来自UITableView文档

  

beginUpdates
  开始一系列插入,删除或的方法调用   选择接收器的行和部分。

这意味着,除非您要插入,删除或选择,否则不应使用此项。你没有做这些。

此外,您应该beginUpdatesendUpdates结束,而不是reloadData。文档:

  

这组方法必须以调用endUpdates结束。

答案 1 :(得分:5)

reloadDatareloadRowsAtIndexPaths之间的第一个区别是,在执行UITableViewCell时,为同一个indexPath分配了两个reloadRowsAtIndexPaths个对象(因为tableview'混合'了新细胞)。 cellForRowAtIndexPath中的代码有时无法预见到这一点。令人惊讶的是,即使已经为特定的单元格标识符分配了一个单元格,表视图也不会在dequeueReusableCellWithIdentifier中为您提供此单元格。在调用reloadRowsAtIndexPaths时,它会返回nil。矛盾reloadData重用已经分配的单元格。

第二个区别是endUpdatesreloadRowsAtIndexPaths之后直接调用cellForRowAtIndexPath(如果在那里设置断点,endUpdates在堆栈跟踪中可见)而{{1}稍后调度reloadData的调用(在堆栈跟踪中不可见)。

但是,您需要发布更多代码,以便让我们了解您在那里所做的事情。原则上,只要不删除或插入行,新单元格的indexPaths与cellForRowAtIndexPath的旧单元格的indexPaths相同。

答案 2 :(得分:1)

如果要同时为后续插入,删除和选择操作(例如,cellForRowAtIndexPath:和indexPathsForVisibleRows)设置动画,请调用此方法。

我认为这就是你想要的。 beginUpdates& endUpdates可以使用动画更改UItableview。