9

I was playing around with Compositional Layouts with Diffable DataSource and so far loving it. But all of my endeavors have included a single type of Data Item.

What I'm trying to achieve is have two different types of List, say Car and Airplane

So far what I've done is created the layouts, created an Enum

enum DataItem: Hashable{
    case cars(Car)
    case airplane(Airplane)
}

And dataSource initialization:

func configureDataSource(){
    dataSource = UICollectionViewDiffableDataSource
    <Section, DataItem>(collectionView: collectionView) {
        (collectionView: UICollectionView, indexPath: IndexPath, dataItem: DataItem) -> UICollectionViewCell in
        
        switch dataItem {
        case .cars(let car):
            guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CarCell.reuseIdentifier, for: indexPath) as? CarCell else {fatalError("Couldn't Create New Cell")}
            ....
            return cell
        case .airplanes(let airplane):
            guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AirplaneCell.reuseIdentifier, for: indexPath) as? AirplaneCell else {
                fatalError("Couldn't Create New Cell")
            }
            ....
            return cell
        }
    }
    dataSource.apply(snapshotForCurrentState(), animatingDifferences: false)
}

Now the part that I'm stuck is creating the snapshot.

Ideally what I'd like to do is

func snapshotForCurrentState() -> NSDiffableDataSourceSnapshot<Section, DataItem>{
    var snapshot = NSDiffableDataSourceSnapshot<Section, DataItem>()
    snapshot.appendSections(Section.allCases)
    snapshot.appendItems([cars], toSection: Section.cars)
    snapshot.appendItems([airplanes], toSection: Section.airplanes)
    return snapshot
}

What am I missing here?

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
n1schal
  • 91
  • 3
  • In order for custom `ItemIdentifier` types (e.g. `DataItem`) to synthesize `Hashable` conformance, their enum case associated types (e.g. `Car` and `Airplane`) have to manually add `Hashable` conformance. – Andrew Kirna Apr 10 '22 at 00:13

1 Answers1

9

You're on the right path. The part you're missing is that you need to create your snapshot with the aggregated type you created, DataItem.

func snapshotForCurrentState() -> NSDiffableDataSourceSnapshot<Section, DataItem>{
    var snapshot = NSDiffableDataSourceSnapshot<Section, DataItem>()
    snapshot.appendSections(Section.allCases)

    let carItems = cars.map { DataItem.car($0) }
    snapshot.appendItems(carItems, toSection: Section.cars)

    let airplaneItems = airplanes.map { DataItem.airplane($0) }
    snapshot.appendItems(airplaneItems, toSection: Section.airplanes)
    return snapshot
}

Ben Scheirman
  • 40,531
  • 21
  • 102
  • 137