1

I have a UICollectionView that I feed data into using UICollectionViewDiffableDataSource. I want to display a scroll scrubber on the trailing edge of it, like I'd get if I implemented the data source methods indexTitlesForCollectionView and indexPathForIndexTitle. But the data source is the diffable data source object, and there's no property or closure on it to supply index titles as of iOS 15.

How are index titles supposed to work with UICollectionViewDiffableDataSource?

Tom Hamming
  • 10,577
  • 11
  • 71
  • 145

1 Answers1

1

You have to create the subclass for your 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)
    }
}

You can use now this custom diffable data source in your vc instead of regular UICollectionViewDiffableDataSource.

N.B But there is a small trick. You must have to setup indexTitles once applying snapshot completes, otherwise it may crash.

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