[英]How hide header on iOS 13 Collection View Compositional Layout
在部署 iOS 13 組合布局時,我遇到了一個奇跡。
我想隱藏集合視圖 header 並實現referenceSizeForHeaderInSection
方法,但是referenceSizeForHeaderInSection
不能在 Compositional Layout 上工作
這是我的組合布局:
lazy var collectionViewLayout: UICollectionViewLayout = {
// item layout deploy
let cellItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(0.2))
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.33), heightDimension: .fractionalHeight(1.0))
let cellItem = NSCollectionLayoutItem(layoutSize: cellItemSize)
let item = NSCollectionLayoutItem(layoutSize: itemSize)
cellItem.contentInsets = NSDirectionalEdgeInsets(top: 4, leading: 4, bottom: 4, trailing: 4)
item.contentInsets = NSDirectionalEdgeInsets(top: 4, leading: 4, bottom: 4, trailing: 4)
// group layout deploy
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(0.2))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 3)
let containerGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(215))
let containerGroup = NSCollectionLayoutGroup.vertical(layoutSize: containerGroupSize, subitems: [cellItem, group, group, group, group])
// section layout deploy
let section = NSCollectionLayoutSection(group: containerGroup)
section.contentInsets = NSDirectionalEdgeInsets(top: 4, leading: 0, bottom: 4, trailing: 0)
// Headers layout deploy
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(18))
let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: SupplementaryViewOfKind.Header.rawValue, alignment: .top)
section.boundarySupplementaryItems = [header]
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}()
實施viewForSupplementaryElementOfKind
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
guard
kind == SupplementaryViewOfKind.Header.rawValue,
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: XXXHeader.identifier, for: indexPath) as? XXXHeader
else { return UICollectionReusableView() }
if isFullScreen {
// customer header with titleLabel property
header.titleLabel.text = segmentedControl.titleForSegment(at: indexPath.section)
} else {
header.titleLabel.text = nil
}
}
然后我嘗試了referenceSizeForHeaderInSection
但無法工作
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
if isFullScreen {
return CGSize(width: collectionView.frame.width, height: 18)
} else {
return CGSize.zero
}
}
是否有任何想法或新方法來隱藏組合布局 header。
生成布局時,可以傳入索引
func generateLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout {(sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
// do your layout stuff here. With sectionIndex, you can layout differently for each section
}
return layout
}
func configureDiffableDataSource() {
let dataSource = UICollectionViewDiffableDataSource<TripSection, TripItem>(collectionView: collectionView) {
(collectionView: UICollectionView, indexPath: IndexPath, item: TripItem) -> UICollectionViewCell? in
let cell = collectionView.dequeueCell(ofType: SmallTableViewCell.self, for: indexPath)
cell.fillWithData(tip)
return cell
}
}
//添加 elementKindSectionHeader 如果 isFullScreen 返回 nil
dataSource.supplementaryViewProvider = { [weak self] (collectionView: UICollectionView, kind: String, indexPath: IndexPath) -> UICollectionReusableView? iln
guard let itamSequence = self?.dataSource?.itemIdentifier(for: indexPath) else { return nil }
guard let section = self?.dataSource?.snapshot().sectionIdentifier(containingItem: itamSequence) else { return nil }
let boardHeader = collectionView.dequeueReusableView(ofType: BoardSupplementaryView.self, forKind: UICollectionView.elementKindSectionHeader, for: indexPath)
return boardHeader
}
}
self.dataSource = dataSource
updateSnapshot(animated: false)
}
目前,除了創建自己的協議來確定是否應在部分中顯示標題之外,似乎沒有其他方法可以做到這一點。 幸運的是, UICollectionViewCompositionalLayout
構造函數為我們提供了節索引,因此很容易做到。 不要為沒有它們的部分創建任何補充視圖。
protocol CollectionViewLayoutProviderDelegate: class {
func layoutProvider(_ provider: CollectionViewLayoutProvider, shouldDisplaySupplementaryViewIn section: Int) -> Bool
}
class CollectionViewLayoutProvider {
weak var delegate: CollectionViewLayoutProviderDelegate?
init(delegate: CollectionViewLayoutProviderDelegate?) {
self.delegate = delegate
}
private func prepareSupplementaryViews(section: Int) -> [NSCollectionLayoutBoundarySupplementaryItem] {
if let delegate = delegate,
!delegate.layoutProvider(self, shouldDisplaySupplementaryViewIn: section) {
// Return empty array to avoid displaying headers
return []
}
// Configure header if you need to
}
private func prepareSection(section: Int, group: NSCollectionLayoutGroup) -> NSCollectionLayoutSection {
let layoutSection = NSCollectionLayoutSection(group: group)
layoutSection.boundarySupplementaryItems = prepareSupplementaryViews(section: section)
return layoutSection
}
}
然后,在你看來 controller
private lazy var layoutProvider = CollectionViewLayoutProvider(delegate: self)
extension YouViewController: CollectionViewLayoutProviderDelegate {
func layoutProvider(_ provider: CollectionViewLayoutProvider, shouldDisplaySupplementaryViewIn section: Int) -> Bool {
return viewModel.shouldDisplayHeader(for: section) != nil
}
}
我所做的:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
if needHideHeaderView {
if let headerView = collectionView.supplementaryView(forElementKind: UICollectionView.elementKindSectionHeader, at: IndexPath(row: 0, section: section)) {
headerView.isHidden = true
}
return CGSize.zero
} else {
// other code
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.