Как мне поддерживать скруббер с быстрой прокруткой с помощью UICollectionViewDiffableDataSource?

#ios #uicollectionview #uicollectionviewdiffabledatasource

Вопрос:

У меня есть UICollectionView , в который я загружаю данные UICollectionViewDiffableDataSource . Я хочу отобразить скруббер прокрутки на его задней кромке, как я бы получил, если бы я реализовал методы источника данных indexTitlesForCollectionView и indexPathForIndexTitle . Но источником данных является объект источника данных с возможностью изменения, и для него нет свойства или закрытия для предоставления заголовков индексов начиная с iOS 15.

С какими заголовками индексов предполагается работать UICollectionViewDiffableDataSource ?

Ответ №1:

Вам необходимо создать подкласс для вашего UICollectionViewDiffableDataSource.

 final class SectionIndexTitlesCollectionViewDiffableDataSource: UICollectionViewDiffableDataSource<Section, SectionItem> {

    private var indexTitles: [String] = []

    func setupIndexTitle() {
        indexTitles = ["A", "B", "C"] 
    }

    override func indexTitles(for collectionView: UICollectionView) -> [String]? {
        indexTitles
    }

    override func collectionView(_ collectionView: UICollectionView, indexPathForIndexTitle title: String, at index: Int) -> IndexPath {
        // your logic how to calculate the correct IndexPath goes here.
        guard let index = indexTitles.firstIndex(where: { $0 == title }) else {
            return IndexPath(item: 0, section: 0)
        }
    
        return IndexPath(item: index, section: 0)
    }
}
 

Теперь вы можете использовать этот настраиваемый настраиваемый источник данных в вашем vc вместо обычного UICollectionViewDiffableDataSource.

N.B Но есть небольшая хитрость. После завершения применения моментального снимка необходимо настроить заголовки индексов, иначе это может привести к сбою.

 dataSource?.apply(sectionSnapshot, to: section, animatingDifferences: true, completion: { [weak self] in
    self?.dataSource?.setupIndexTitle()
    self?.collectionView.reloadData()
})