#ios #swift #uicollectionview #uicollectionviewcompositionallayout
Вопрос:
Я пытаюсь создать представление коллекции с композиционной компоновкой, состоящей из нескольких разделов
но если в разделах есть пустые элементы, как я могу с этим справиться?
если элемент пуст, я не хочу показывать этот раздел
UICollectionViewCompositionalLayout { (section, env) -> NSCollectionLayoutSection? in
// do I have to code in this area?
}
Комментарии:
1. У вас есть пустой массив источников данных для первого раздела (например
[[],[image, image, image ...]]
)? Или внутри него есть элементы (которые не видны, возможно, потому, что изображение равно нулю)?
Ответ №1:
Если вы также используете UICollectionViewDiffableDataSource, вы можете иметь дело с пустыми разделами при создании/обновлении снимков — добавляйте только разделы с элементами в нем.
В своем проекте я делаю что-то вроде этого:
func performQuery(animate: Bool) {
var currentSnapshot = NSDiffableDataSourceSnapshot<Section, ViewCell>()
if !calendars.isEmpty {
currentSnapshot.appendSections([Section(name: "main")])
currentSnapshot.appendItems(calendars, toSection: Section(name: "main"))
}
if !lifeCals.isEmpty {
currentSnapshot.appendSections([Section(name: "life")])
currentSnapshot.appendItems(lifeCals, toSection: Section(name: "life"))
}
dataSource.apply(currentSnapshot, animatingDifferences: animate)
}
Таким образом, если у пользователя 0 календарей жизни, раздела «жизнь» не будет.
Ответ №2:
У меня была та же проблема, и я решил ее так:
import UIKit
final class CollectionViewCompositionalLayout: UICollectionViewCompositionalLayout {
override init(sectionProvider: @escaping UICollectionViewCompositionalLayoutSectionProvider) {
weak var weakSelf: CollectionViewCompositionalLayout?
super.init { section, environment in
guard
let strongSelf = weakSelf,
let collectionView = strongSelf.collectionView,
let dataSource = collectionView.dataSource,
dataSource.collectionView(collectionView, numberOfItemsInSection: section) == 0
else {
return sectionProvider(section, environment)
}
return strongSelf.emptySectionLayout()
}
weakSelf = self
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension CollectionViewCompositionalLayout {
private enum Constants {
static let size: CGFloat = 0.1
}
private func emptySectionLayout() -> NSCollectionLayoutSection {
let size = NSCollectionLayoutSize(
widthDimension: .estimated(Constants.size),
heightDimension: .estimated(Constants.size)
)
let item = NSCollectionLayoutItem(
layoutSize: size
)
let group = NSCollectionLayoutGroup.vertical(
layoutSize: size,
subitems: [item]
)
let emptySectionLayout = NSCollectionLayoutSection(group: group)
return emptySectionLayout
}
}
Это выглядит не очень хорошо, но работает довольно хорошо 🙂