可区分的集合视图如何在多个部分中显示相同的项目?

Posted

技术标签:

【中文标题】可区分的集合视图如何在多个部分中显示相同的项目?【英文标题】:How can a diffable collection view display the same item in multiple sections? 【发布时间】:2020-06-15 21:46:15 【问题描述】:

我的应用提供了一个类似于 Apple 的表情符号键盘,其中表情符号按类别显示。我使用类别为部分的集合视图来呈现它。如果最近插入了表情符号,它应该出现在“常用”类别以及它通常所在的任何类别中。

这对我试图将我的集合视图转换为使用UICollectionViewDiffableDataSource 时是个问题,因为NSDiffableDataSourceSnapshot 要求项目是唯一的。如果我做类似的事情

let snapshot = NSDiffableDataSourceSnapshot<Section, Emoji>()
snapshot.appendItems([thumbsUpEmoji], toSection: .frequents)
snapshot.appendItems([thumbsUpEmoji], toSection: .smileys)
dataSource.apply(snapshot)

我收到类似警告

插入的标识符已经存在;现有项目将被移动到当前插入的位置。请注意,如果项目在插入时不是唯一的,这将影响性能。

表情符号只显示在一个部分,而不是两个。如何将项目插入多个部分?

【问题讨论】:

【参考方案1】:

我发现我可以通过将表情符号包装在将表情符号与其部分相关联的结构中来做到这一点:

struct CategorizedEmoji: Hashable 
    let emoji: Emoji
    let category: Section

我的数据源类型为UICollectionViewDiffableDataSource&lt;Section, CategorizedEmoji&gt;,快照类型为NSDiffableDataSourceSnapshot&lt;Section, CategorizedEmoji&gt;。在构建快照时我会这样做

let snapshot = NSDiffableDataSourceSnapshot<Section, CategorizedEmoji>()
snapshot.appendItems([CategorizedEmoji(emoji: thumbsUpEmoji, category: .frequents)], toSection: .frequents)
snapshot.appendItems([CategorizedEmoji(emoji: thumbsUpEmoji, category: .smileys)], toSection: .smileys)
dataSource.apply(snapshot)

有点冗长,但真的还不错。

警告:我猜这个解决方案会阻止表情符号在部分之间移动(因为不同部分中的表情符号将由完全不同的项目表示)。我个人不需要处理这个问题,但我很高兴看到一个能解决这个问题的答案。

【讨论】:

我刚刚遇到同样的问题并像这样解决了它。我的心智模型是:CategorizedEmoji 是视图或 viewModel 数据的唯一表示,而不是与我的基础数据模型的直接 1-1。如果您的表情符号更新,您仍然可以找到所有 CategorizedEmoji 结构并更新它们。 @Morgz 我喜欢这种心智模型。回复:更新表情符号,是的,我可以找到所有 CategorizedEmoji 结构并更新它们。我的意思是我认为集合视图会将更新视为从一个部分中删除并在另一部分中插入而不是在部分之间移动,因为新部分中的结构不会散列到与旧部分中的结构。不过我还没有测试过。

以上是关于可区分的集合视图如何在多个部分中显示相同的项目?的主要内容,如果未能解决你的问题,请参考以下文章

word中一共有几种视图方式,并且如何区分几种视图关系,如:页面视图、大纲视图等等

如何使用情节提要将集合视图部分项目滚动到水平

集合视图内容未显示在视图中

依次显示两个相同的警报视图。如何区分来自警报 1 和警报 2 的文本?

如何在多个视图部分重用 angularjs 数据?

独立填充集合视图的每个部分 Swift