ios - How can a diffable collection view display the same item in multiple sections?
问题描述
My app presents an emoji keyboard like Apple's where the emoji are displayed by-category. I render this using a collection view where the categories are sections. If an emoji has been inserted recently, it should appear in the "Frequently Used" category as well as whatever category it's normally in.
This is a problem for me trying to convert my collection view to use a UICollectionViewDiffableDataSource
, because NSDiffableDataSourceSnapshot
requires that items are unique. If I do something like
let snapshot = NSDiffableDataSourceSnapshot<Section, Emoji>()
snapshot.appendItems([thumbsUpEmoji], toSection: .frequents)
snapshot.appendItems([thumbsUpEmoji], toSection: .smileys)
dataSource.apply(snapshot)
I get warnings like
inserted identifier(s) already present; existing items will be moved into place for this current insertion. Please note this will impact performance if items are not unique when inserted.
And the emoji only shows up in one section, not both. How can I insert the item into multiple sections?
解决方案
I found that I was able to do this by wrapping the emoji in structs that associated the emoji to their sections:
struct CategorizedEmoji: Hashable {
let emoji: Emoji
let category: Section
}
My datasource is then of type UICollectionViewDiffableDataSource<Section, CategorizedEmoji>
and the snapshots of type NSDiffableDataSourceSnapshot<Section, CategorizedEmoji>
. When constructing the snapshot I do
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)
A little verbose but really not too bad.
Caveat: I would guess that this solution would prevent the emoji from moving between sections (since an emoji in a different section would be represented by a completely different item). I personally don't need to handle that but I'd welcome seeing an answer that did figure that out.
推荐阅读
- android - Android Studio Socket Server 以编程方式获取 ipv4 地址
- c# - C#/XAML 从包含字符串的 Linq 查询中分配选取器列表 ItemsSource 属性错误:CS0029
- python - 在 Azure Devops 管道中安装 Python 要求时出错
- iframe - 有没有办法在不禁用 Flash 的情况下防止 iframe 重定向父页面
- javascript - 为什么续集 beforeUpdate 挂钩不起作用?
- javascript - 试图从包含 API 地址的数组字符串中获取数据
- c# - 如何使用 radioButton 在 Aspnet mvc4 中创建动态列表?
- r - 使用 dplyr / magrittr 传递分组的 data.frame
- c - printf不在C中打印
- javascript - 使用 nodemailer 一次发送多封电子邮件