UICollectionViewCompositionalLayout не может использовать те же разделы, что и UICollectionViewDiffableDataSource?
Я создаю контроллер представления с представлением коллекции, используя (своего рода) новый источник данных для различий и составной макет представления коллекции. Я сделал свои собственные перечисления Section и Row, могу реагировать на изменения в моей модели (массив фотографий), что вызывает
applySnapshot
и все работает.
Но.. по моему
createLayout
функция У меня есть только индекс раздела для работы?? Мне это кажется очень странным, почему эти две технологии не работают лучше вместе? Один работает с
SectionIdentifierType
и
ItemIdentifierType
(отлично!), а другой по-прежнему основан на индексах? Тьфу.
Я хочу сделать что-то вроде этого: все ячейки внутри
Section.header
Раздел должен быть на всю ширину экрана с автоматической высотой. Каждая ячейка в
Section.photos
раздел получит фиксированный размер. Также могут быть другие разделы с разными размерами ячеек, а некоторые разделы могут быть необязательными. Таким образом, с системой на основе индексов действительно сложно работать, нельзя жестко запрограммировать, что раздел 0 - это заголовок, а раздел 1 - это фотографии: порядок может меняться, все может быть необязательным и т. Д.
Что лучше с этим справиться? Я, конечно, могу хранить массив
[Section]
на контроллере представления используйте индекс раздела, чтобы получить
Section
в таком случае, но нет ли встроенного способа получить идентификатор раздела для индекса? Это кажется вполне логичным, поскольку эти две технологии были выпущены одновременно.
class PhotosViewController: UIViewController {
enum Section: Equatable, Hashable {
case header
case photos
}
enum Row: Equatable, Hashable {
case header
case photo(Photo)
}
private lazy var dataSource = makeDataSource()
var photos: AnyPublisher<[Photo], Never>!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.collectionViewLayout = createLayout()
photos
.sink(receiveValue: applySnapshot)
.store(in: &subscriptions)
}
private func makeDataSource() -> UICollectionViewDiffableDataSource<Section, Row> {
return UICollectionViewDiffableDataSource(collectionView: collectionView) { (collectionView, indexPath, item) -> UICollectionViewCell? in
switch item {
case .header:
let cell = collectionView.dequeueReusableCell(for: indexPath, cellType: ProfileHeaderCollectionViewCell.self)
return cell
case .photo(let photo):
let cell = collectionView.dequeueReusableCell(for: indexPath, cellType: PhotoCollectionViewCell.self)
cell.configure(photo: photo)
return cell
}
}
}
private func applySnapshot(photos: [Photo]) {
var snapshot = NSDiffableDataSourceSnapshot<Section, Row>()
let headerSection = Section.header
snapshot.appendSections([headerSection])
snapshot.appendItems([.header], toSection: headerSection)
let items = photos.map { Row.photo($0) }
let photosSection = Section.photos
snapshot.appendSections([photosSection])
snapshot.appendItems(items, toSection: photosSection)
dataSource.apply(snapshot, animatingDifferences: false)
}
private func createLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout { [unowned self] sectionIndex, _ in
// I have to work with a sectionIndex instead of a Section case?
}
return layout
}
}
1 ответ
Вместо того, чтобы отслеживать идентификаторы разделов в отдельном массиве, к счастью, вы можете просто использовать
dataSource.snapshot().sectionIdentifiers[sectionIndex]
.