CollectionView с использованием NSDiffableDataSource с UICollectionViewFlowLayout - PullRequest
0 голосов
/ 02 мая 2020

Когда я использую UICollectionView с установленным UICollectionViewFlowLayout. А затем попробуйте применить моментальные снимки источника данных через

// load initial data
        reloadDataSource()

        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
            self.reloadDataSource(animating: true)
        }

. Я получаю cra sh для второго снимка, примененного с задержкой в ​​3 секунды. Cra sh происходит только при анимации: true

Если я установил animating в false, то cra * sh не будет, но представление коллекции, если оставить пустым.

Вот этот метод применения источника данных

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 () в фоновую очередь, другая очередь приводит к пустым данным в collectionview

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 Ответ

0 голосов
/ 02 мая 2020

Хорошо, похоже, что я нашел причину всех моих ошибок при обновлении источника данных путем применения новых снимков

Этот ленивый источник данных 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.

...