Closed xinsight closed 4 years ago
I think i figured it out. :)
Creating the data source to produce a more generic AnyHashable
allows any type of object to be created. So, you just need to cast the AnyHashable to your specific class. For example:
lazy var dataSource = CollectionViewDiffableDataSource<Section, AnyHashable> (collectionView: collectionView) { collectionView, indexPath, item in
if let article = item as? Article, let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Section.articles.cellIdentifier, for: indexPath) as? ArticleCollectionViewCell {
cell.article = article
return cell
}
if let trend = item as? Trend, let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Section.trends.cellIdentifier, for: indexPath) as? TrendSummaryCell {
cell.trend = trend
return cell
}
fatalError()
}
I also found it useful to have a function to create the snapshot, and can then call it when my arrays are updated.
func buildSnapshot() -> DiffableDataSourceSnapshot<Section, AnyHashable> {
let snapshot = DiffableDataSourceSnapshot<Section, AnyHashable>()
snapshot.appendSections([.trends, .articles])
snapshot.appendItems(trends, toSection: .trends)
snapshot.appendItems(articles, toSection: .articles)
return snapshot
}
var articles: [Article] = [] {
didSet {
let snapshot = buildSnapshot()
dataSource.apply(snapshot, animatingDifferences: true)
}
}
var trends: [Trend] = [] {
didSet {
let snapshot = buildSnapshot()
dataSource.apply(snapshot, animatingDifferences: true)
}
}
Hi @xinsight .
You can use enum for multiple type data source items.
e.g:
enum Item: Hashable {
case article(Article)
case trend(Trend)
}
func viewDidLoad() {
super.viewDidLoad()
let snapshot = DiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.trends, .articles])
dataSource.apply(snapshot)
}
func appendArticles(_ articles: [Article]) {
let snapshot = dataSource.snapshot()
snapshot.appendItems(articles.map { .article($0) }, toSection: .articles)
dataSource.apply(snapshot)
}
func appendTrends(_ trends: [Trend]) {
let snapshot = dataSource.snapshot()
snapshot.appendItems(trends.map { .trend($0) }, toSection: .trends)
dataSource.apply(snapshot)
}
Checklist
Expected Behavior
I'd like to use DiffableDataSources with different cell types.
Current Behavior
I'm able to create a single data source and single cell type and apply the changes. I'm obviously missing something because I cannot figure out how to create a data source that vends multiple object types. (I tried creating multiple data sources, but then ended up with the dreaded UICollectionView exceptions about
attempt to delete item 2 from section 0 which only contains 2 items before the update
.)Detailed Description (Include Screenshots)
Here is how I'm creating "article" cells. I'm not sure how to create another cell type.
Environment
version: 0.1.0
Swift version: 5.0
iOS version: 12.2
Xcode version: 10.2.1
Devices/Simulators: iPhone X
CocoaPods/Carthage version: 0.33.0