DiffableDataSource: снимок не перезагружает верхние и нижние колонтитулы - PullRequest
3 голосов
/ 30 января 2020

Я использую UICollectionViewDiffableDataSource для UICollectionView для отображения содержимого в нескольких разделах.

Я использую Композиционный макет представления представления и источники данных с разным доступом ссылка , представленная на WWD C '19 для рендеринга макета с несколькими разделами UICollectionView

У меня есть простая настройка, заголовок для каждого раздела показывает количество элементов в этом разделе, а нижний колонтитул показывает сводку всех элементов раздела.

Заголовок секции 1 -> Январь 2020 - 5 поездок
Секция 1, пункт 1 -> Поездка 1
Секция 1, пункт 2 -> Поездка 2
Секция 1, пункт 3 -> Поездка 3
раздел 1, элемент 4 -> Поездка 4
раздел 1, пункт 5 -> Поездка 5

сейчас. Если отключение удалено, DiffableDataSource обновляет изменяется по анимации, но не перезагружает заголовки разделов. Что выглядит противоречивым. Например, если «Поездка 4» была удалена, тогда «Заголовок» все еще показывает, что в разделе есть 5 поездок. Как сделать так, чтобы заголовки также перезагружались с DiffableDataSource?

для временного исправления, я просто вызываю collectionView.reloadData() после задержки, которая показывает анимацию Diffing, а затем я перезагружаю данные, которые заставляют заголовок быть перезагруженным а также.

private func configureTripDataSource(){
    tripDataSource = UICollectionViewDiffableDataSource<MonthSection, Trip>(collectionView: tripsCollectionView, cellProvider: { (collectionView, indexPath, trip) -> UICollectionViewCell? in

        // Get a cell of the desired kind.
        guard let cell = collectionView.dequeueReusableCell(
            withReuseIdentifier: TripInfoCell.reuseIdentifier,
            for: indexPath) as? TripInfoCell else { fatalError("Cannot create new TripInfoCell") }

        // Populate the cell with our item description.
        cell.trip = trip

        // Return the cell.
        return cell

    })

    tripDataSource.supplementaryViewProvider = {
       [weak self] (collectionView: UICollectionView, kind: String, indexPath: IndexPath) -> UICollectionReusableView? in

        guard let self = self else {return nil}

        if kind == TripsController.tripsMonthSectionHeaderElementKind{

            // Get a supplementary view of the desired kind.
            guard let header = collectionView.dequeueReusableSupplementaryView(
                ofKind: kind,
                withReuseIdentifier: TripSectionHeaderCell.reuseIdentifier,
                for: indexPath) as? TripSectionHeaderCell else { fatalError("Cannot create new header") }

            // setup header

            let currentSnapShot = self.tripDataSource.snapshot()
            let tripMonthSection = currentSnapShot.sectionIdentifiers[indexPath.section]

            header.titleLabel.text = tripMonthSection.title
            header.subtitleLabel.text = "\(tripMonthSection.trips.count) Trips"

            return header

        } else {
            return UICollectionReusableView()
        }

    }

    var snapshot = NSDiffableDataSourceSnapshot<MonthSection, Trip>()

    let allSections = self.tripsStore.monthSections
    snapshot.appendSections(allSections)
    for section in allSections{
        snapshot.appendItems(section.trips, toSection: section)
    }

    self.tripDataSource.apply(snapshot, animatingDifferences: true)
}

1 Ответ

2 голосов
/ 11 марта 2020

Чтобы вызвать автоматическую c перезагрузку заголовков ваш Раздел объект должен быть Hashable и должен иметь все необходимые свойства, сохраненные для создания уникального объекта. sh для Секции.

Именно поэтому все объекты объектов и Item объектов должны иметь Hashable , и они должны возвращать уникальный ha sh, чтобы разрешить DiffableDataSource для управления их перезагрузкой, только если их значения были изменены.

Например:

struct MonthSection: Hashable {
   var title: String
   var itemsCount: Int
}

И затем:

var section = MonthSection(title: "Title", itemsCount: 5)
.....
snapshot.appendSections([section])
snapshot.appendItems(items, toSection: section)

Любое изменение заголовка или количества элементов для раздела во время следующего обновления снимка будет инициировано заголовок раздела для перезагрузки, и он будет работать как волхвы c!

...