【问题标题】:TableView reloadData vs. beginUpdates & endUpdatesTableView reloadData vs. beginUpdates & endUpdates
【发布时间】:2011-12-31 17:18:15
【问题描述】:

我在更新我的 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 的两种方式之间是否有区别(当然除了动画位)还是我应该怀疑问题出在其他地方? p>

编辑: 好的,我将尝试解释症状是什么:

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

btn.tag = indexPath.row;

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

- (void)btnPressed:(id)sender

当我随后更新单元格时 - 因为单元格中的某些值已更改 - 情况 1 使一切正常,但是情况 2 - 混合了标签,因此下次按下其中一个按钮时,它们不再具有正确的标签。

在我看来,混淆确实是随机的,但随机化的发生方式会有所不同,具体取决于我首先按下的单元格按钮。我希望这能澄清我的问题。

【问题讨论】:

  • “我得到不同的结果”,“这不能按预期工作。”以什么方式?
  • 好吧,每个单元格在创建时都有一个按钮,带有一个标签,其中the button tag = the index path row。在情况 1 中,按钮获得正确的标签,在情况 2 中 - 它没有。

标签: ios objective-c reloaddata


【解决方案1】:

来自UITableView 文档

开始更新
开始一系列插入、删除或 选择接收器的行和部分。

这意味着,除非您正在插入、删除或选择,否则您不应该使用它。这些你都没有做。

另外,您应该以endUpdates 结尾beginUpdates,而不是reloadData。文档:

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

【讨论】:

  • 啊,是的,reloadData-bit 是我帖子中的错字——我的错。
  • 好吧,这就是 reloadData 和 beginUpdates/endUpdates 之间的区别,但我真的不知道这些区别应该如何影响我的结果。我意识到我在描述后果时有点含糊,我会在几分钟内更新我原来的问题。
  • 尝试删除beginUpdatesendUpdates。他们不属于updateRowsAtIndexPaths
  • Mundi - 带有beginUpdatesendUpdates-标签的单元格中的值已正确更新,不幸的是,单独使用[tbl reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationRight];似乎没有更新任何内容。
  • 有趣。在我的一个项目中,没有这些也可以。我会调查的。
【解决方案2】:

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

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

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

【讨论】:

  • 谢谢你的回答狮子座。已经有几年了,我不记得这个项目发生了什么,但我怀疑我是否曾经解决过它,希望这个 Q 以及你和@Mundi 给出的答案可以帮助其他有类似问题的人。
【解决方案3】:

如果您希望后续的插入、删除和选择操作(例如 cellForRowAtIndexPath: 和 indexPathsForVisibleRows)同时进行动画处理,请调用此方法。

我想这就是你想要的。 beginUpdates & endUpdates 可以用动画改变 UItableview。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    相关资源
    最近更新 更多