0

我是领域的新手,正在尝试使用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)
}

非常感谢您对此提供的帮助。谢谢!

4

0 回答 0