在表格视图中重新加载数据而不损害动画

Posted

技术标签:

【中文标题】在表格视图中重新加载数据而不损害动画【英文标题】:Reload data in table view without harming animation 【发布时间】:2016-07-15 19:43:38 【问题描述】:

我有一个基于 UITableView 的游戏内商店。

每个单元格都有一个“购买”按钮,该按钮大部分处于启用状态,如果项目是一次性购买,则可以切换到“购买”,如果没有足够的钱,则可以禁用。

现在我所做的是每次按下购买按钮时调用reloadData 以更新可见单元格和当前单元格本身。 (我必须更新所有单元格,因为购买后可能没有足够的钱购买可见的项目单元格)。

但它会导致奇怪的动画故障,例如当我单击一个单元格的购买按钮时,动画在另一个单元格上结束。

我认为这是由于单元格的可重用性而发生的。所以我想知道的是如何在不损害原生动画的情况下重新加载整个表格视图中的数据。

我唯一能想到的就是不要使用可重用单元并将它们全部缓存,但我认为这不是一个好的编程习惯。

【问题讨论】:

【参考方案1】:

首先,确保您的视图层和模型层是分开的。应该有一些知道每个项目的非视图对象;我们称之为Item

现在,创建一个ItemCell(您可能已经有一个)。那是你的可重复使用的细胞。把它交给Item。它应该根据那里的数据进行自我配置。

使用 KVO、委托或通知让单元格观察其项目。当Item 更改其状态时,单元格应更新其自己的按钮。

当您的单元格被重复使用时,您将向其传递一个新的item。它应该停止观察前一个,并开始观察新的(当然要重新配置自己以匹配当前状态)。

通过将视图(可重用和临时)与模型(稳定且长期存在)分离,您可以通过正确的动画获得单元重用的性能优势,而无需调用reloadData

【讨论】:

好吧,当细胞知道它的模型时,我认为这是一个糟糕的设计...... 而且我看不出它如何帮助我更新其他单元格以查看他们是否有钱 知道如何显示特定模型类的单元格是出色的设计,可以追溯到 SmallTalk。只要它只是观察模型并不断提供它的视觉表示。单元格只是一个视图。如果他们需要知道总金额,您可以交给他们一个“帐户”对象。 好吧,但我仍然不明白如何更新其他单元格。假设我的商店中有 64 件商品。我将它们的模型存储在一个数组中,然后为适当的对象创建一个可重用的单元格。一旦我点击购买按钮,您希望我更新所有 64 件商品,比如说使用一些布尔标志“canBeBought”,然后只会观察到其中的少数商品,因为一次只有 3-4 件商品可见。我是不是误会了什么? 不,一点也不。首先,当您按下购买按钮时,它应该转到控制器,它应该更新模型。当前视图应该观察模型并看到类似“AccountBalanceDidChangeNotification”(或 KVO 或观察者模式,或其他)之类的内容,并相应地更新自己。如果一次只有 3 或 4 个可见,那么将只有 3 或 4 个(或者可能 5 或 6 个)视图存在。这就是回收的工作原理。【参考方案2】:

您可以在单元格类中有一个reloadCell 方法并循环遍历表格的visibleCells 并以这种方式更新它们的用户界面。这样一来,它们就不会被重新创建(或重复使用),它们只是具有可能因更新新数据而发生变化的相关 UI 部分。

【讨论】:

这可行,但我需要告诉 cell 它的型号,而这正是我要避免的 您最初以某种方式设置单元格,只需使用相同的方法再次设置即可。

以上是关于在表格视图中重新加载数据而不损害动画的主要内容,如果未能解决你的问题,请参考以下文章

如何在uitableview中加载数据而不每次都重新加载

重新加载 UITableView 数据而不重新加载视图?

用动画重新加载表格视图单元格(Swift)

单击按钮后在视图中加载数据而不重新加载页面asp.net mvc中的所有数据

重新加载 UITableView 而不重新加载标题部分

如果从不同的视图控制器按下返回,则重新加载而不重新加载。迅速