CollectionView с использованием NSDiffableDataSource с UICollectionViewFlowLayout
Когда я использую UICollectionView с установленным UICollectionViewFlowLayout. А затем попробуйте применить снимки источника данных через
// load initial data
reloadDataSource()
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
self.reloadDataSource(animating: true)
}
Я получаю сбой при применении второго снимка после 3-секундной задержки. Вылет происходит только при анимации: true
Если я установил для анимации значение false, сбоя не будет, но если оставить пустой вид коллекции.
Вот этот метод применения источника данных
extension CollectionViewController {
func reloadDataSource(animating: Bool = false) {
print("reloading data source with snapshot -> \(snapshot.numberOfItems)")
self.dataSource.apply(self.snapshot, animatingDifferences: animating) {
print("applying snapshot completed!")
}
}
}
Источник данных просто
let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView, cellProvider: cellProvider)
Полный проект, в который вы можете играть (со временем может измениться): https://github.com/michzio/SwifUICollectionView
Обновить
Я попытался упростить пример и сделать что-то вроде этого, но он работает неправильно. Кажется, что перемещение.apply() в фоновую очередь, другая очередь вызывает пустые данные в коллекции
func reloadDataSource(animating: Bool = false) {
print("reloading data source with snapshot -> \(snapshot.numberOfItems)")
diffQueue.async {
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.categories])
snapshot.appendItems(Item.categoryItems)
self.dataSource.apply(snapshot, animatingDifferences: animating) {
print("applying snapshot completed!")
}
}
}
1 ответ
Хорошо, похоже, я нашел причину всех своих ошибок с обновлением источника данных, применив новые снимки
Этот ленивый источник данных var вызывает ошибки:
private(set) lazy var dataSource: UICollectionViewDiffableDataSource<Section, Item> = {
let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView, cellProvider: cellProvider)
//dataSource.supplementaryViewProvider = supplementaryViewProvider
return dataSource
}()
Я изменил это на
private(set) var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
и после configureCollectionView в viewDidLoad() теперь я вызываю configureDataSource(), который выполняет то, что было в инициализаторе lazy var.