如何移除 UITableView (MonoTouch) 中可重用的单元格

Posted

技术标签:

【中文标题】如何移除 UITableView (MonoTouch) 中可重用的单元格【英文标题】:How to remove cells that can be reused in UITableView (MonoTouch) 【发布时间】:2011-11-07 03:05:15 【问题描述】:

我们有一个场景,当用户在不同的 UITableView 中选择一个项目时,我们重用相同的 UITableView 来显示来自数据库的不同记录集(在概念上类似于 splitviewcontroller,但都在同一个视图中)。

当用户选择不同的区域进行查看时,我们从数据库中获取相应的记录,用新的记录集更新 Source,然后调用 ReloadData。

问题是UITableView中的一些单元格仍然存在,并且在列表之间切换时被重复使用,导致各行数据无效或重叠。

我的问题是:有没有一种方法可以告诉 UITableView 丢弃所有现有的单元格,包括那些排队等待重用的单元格?我本来希望 ReloadData 执行此任务,但它没有。

更新说明:

我们表格中的每个单元格都由可变数量的子视图组成(我们试图模仿网格控件)。当用户在左侧导航中选择不同的列表时,不能保证新选择的列表中的子视图位置(列)会与前一个列表中的位置重叠。这就是为什么我们正在寻找一种方法来删除排队的单元格。

【问题讨论】:

【参考方案1】:

由于这是其他人可能会遇到的情况,我将发布我们使用的解决方案,但我仍然对更多“原生”方式感兴趣。

这是我们解决问题的方法:

当正在显示的记录集发生更改时,我们会使用当前单元格配置的唯一标识符(即用户当前查看的数据列表)更新 UITableView。

然后我们创建了一个自定义版本的 UITableViewCell,并在创建时将唯一的列表标识符记录在单元格中。

当我们将一个可重复使用的单元格出列时,我们将视图的当前唯一标识符与存储在单元格中的唯一标识符进行比较,如果它们不匹配,我们将丢弃该单元格并创建一个新单元格。

希望这会帮助别人。

【讨论】:

你怎么能丢弃单元格?是否会导致内存泄漏,因为您从未使用过该单元格,并且该单元格仍存储在 UITableView 的可重用缓存中。【参考方案2】:

ReloadData 不会清除重用队列。它只是触发回调以重新读取重新加载行的数据。随着每个单元的加载,如果您将其从重用队列中取出,它仍将被使用。即使重新使用表格视图也很好,因为单元格类型是相同的,尤其是因为您使用 CellIdentifier 来确保这一点。

但是,您重叠的数据有点奇怪。当您从重用队列中取出一个单元格时,您如何将数据放入其中?您是直接在单元格上绘制数据吗?您是否使用数据添加子视图(导致多组重叠数据)?通常,一个单元格包含像文本标签这样的子视图,并且在它们上面设置了数据,因此不会出现数据重叠的情况 - 单元格的子视图只是更新了它们的数据......

【讨论】:

对不起,我忘了提到关于包含子视图的单元格的部分。我已经用其他信息更新了这个问题。【参考方案3】:

您的 GetCell 方法需要确保已使用将要显示的新数据完全配置了已出队的单元格。

一个常见的错误是假设仅将单元格出列以进行显示会给您一个可以使用的新单元格。

如果您对单元格进行了任何自定义,例如添加视图、修改其属性(图像、披露指示符、背景颜色),您必须确保在重用单元格的 GetCell 方法中,这些属性中的每一个都是在返回单元格之前正确设置。

【讨论】:

谢谢,我绝对理解 GetCell 背后的概念以及每次通过时正确配置单元格的必要性。然而,由于没有任何本机可用于将单元格与更高级别的概念(例如它所属的列表)相关联,我正在寻找一种方法来刷新标记为重用的单元格的缓存,而不必采取我们最终实施的更长的路。

以上是关于如何移除 UITableView (MonoTouch) 中可重用的单元格的主要内容,如果未能解决你的问题,请参考以下文章

移除 UITableView 的边框,而不是分隔符

在 UITableView 中滚动时移除 UIView

iOS UITableView 移除单元格选中时的高亮状态

iOS 移除 UITableView 下面的多余空间

从 UITableView 隐藏单元格

从 UITabBarController 的 moreNavigationController 中移除 rightBarButtonItem