我是领域的新手,正在尝试使用UICollectionViewDiffableDataSource
. 但是,我发现在插入/删除新对象后很难更新数据源。我试图更新,NotificationToken
但它崩溃了。这是我到目前为止尝试过的代码:
fileprivate let realm = try! Realm()
fileprivate var notificationToken: NotificationToken?
fileprivate var items: Results<Item>?
fileprivate enum Section: String, CaseIterable, Hashable {
case main
}
fileprivate typealias DataSource = UICollectionViewDiffableDataSource<Section, Item>
fileprivate typealias Snapshot = NSDiffableDataSourceSnapshot<Section, Item>
fileprivate lazy var dataSource = itemsDataSource()
fileprivate func itemsDataSource() -> DataSource {
let dataSource = DataSource(collectionView: itemsCollectionView) { collectionView, indexPath, item in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! STItemCell
cell.titleLabel.text = item.name
return cell
}
return dataSource
}
fileprivate func bind() {
items = realm.objects(Item.self).sorted(byKeyPath: "order").filter("isDeleted == false")
notificationToken = items?.observe({ [weak self] changes in
guard let datasource = self?.datasource else { return }
switch changes {
case .initial:
self?.applySnapshot()
case .update(_, deletions: let deletions, insertions: let insertions, modifications: let modifications):
var snapshot = datasource.snapshot()
if !deletions.isEmpty {
let itemIdentifiers = deletions.compactMap { item in
return datasource.itemIdentifier(for: IndexPath(item: item, section: 0))
}
snapshot.deleteItems(itemIdentifiers)
}
if !insertions.isEmpty {
let itemIdentifiers = insertions.compactMap { item in
return datasource.itemIdentifier(for: IndexPath(item: item, section: 0))
}
// snapshot.insertItems(...) // Don't know how to implement this...
}
if !modifications.isEmpty {
let itemIdentifiers = modifications.compactMap { item in
return datasource.itemIdentifier(for: IndexPath(item: item, section: 0))
}
snapshot.reloadItems(itemIdentifiers)
}
datasource.apply(snapshot, animatingDifferences: true)
case .error(let error):
fatalError("\(error)")
}
})
}
fileprivate func applySnapshot(animatingDifferences: Bool = true) {
var snapshot = Snapshot()
snapshot.appendSections([.main])
guard let items = items else { return }
snapshot.appendItems(Array(items))
datasource.apply(snapshot, animatingDifferences: animatingDifferences)
}
非常感谢您对此提供的帮助。谢谢!