TL;博士
UICollectionViewCompositionalLayout
有一个configuration
可以通过创建UICollectionViewCompositionalLayoutConfiguration
对象来设置的属性。这个对象有一些非常好的和有用的功能,比如boundarySupplementaryItems
属性。
从文档:
与整个布局的边界边缘相关联的补充项数组,例如全局页眉和页脚。
答对了。设置此属性并在您的数据源中进行必要的接线,您应该有您的全局标头。
代码示例
在这里,我在布局中声明了一个全局标题。标头是视觉效果视图中的分段控件,但您的可以是UICollectionReusableView
.
enum SectionLayoutKind: Int, CaseIterable {
case description
}
private var collectionView: UICollectionView! = nil
override func viewDidLoad() {
super.viewDidLoad()
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createLayout())
}
static func descriptionSection() -> NSCollectionLayoutSection {
// Instantiate and return a `NSCollectionLayoutSection` object.
}
func createLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout {
(sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
// Create your section
// add supplementaries such as header and footers that are relative to the section…
guard let layoutKind = SectionLayoutKind(rawValue: sectionIndex) else { return nil }
let section: NSCollectionLayoutSection
switch layoutKind {
case .description:
section = Self.descriptionSection()
}
return section
}
/*
✨ Magic starts HERE:
*/
let globalHeaderSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(44))
Constants.HeaderKind.globalSegmentedControl, alignment: .top)
let globalHeader = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: globalHeaderSize, elementKind: Constants.HeaderKind.space, alignment: .top)
// Set true or false depending on the desired behavior
globalHeader.pinToVisibleBounds = true
let config = UICollectionViewCompositionalLayoutConfiguration()
/*
If you want to do spacing between sections.
That's another big thing this config object does.
If you try to define section spacing at the section level with insets,
the spacing is between the items and the standard headers.
*/
config.interSectionSpacing = 20
config.boundarySupplementaryItems = [globalHeader]
layout.configuration = config
/*
End of magic. ✨
*/
return layout
}
struct Constants {
struct HeaderKind {
static let space = "SpaceCollectionReusableView"
static let globalSegmentedControl = "segmentedControlHeader"
}
}
数据源部分的补充代码:
let globalHeaderRegistration = UICollectionView.SupplementaryRegistration<SegmentedControlReusableView>(elementKind: Constants.HeaderKind.globalSegmentedControl) { (header, elementKind, indexPath) in
// Opportunity to further configure the header
header.segmentedControl.addTarget(self, action: #selector(self.onSegmentedControlValueChanged(_:)), for: .valueChanged)
}
dataSource.supplementaryViewProvider = { (view, kind, indexPath) in
if kind == Constants.HeaderKind.globalSegmentedControl {
return self.collectionView.dequeueConfiguredReusableSupplementary(using: globalHeaderRegistration, for: indexPath)
} else {
// return another registration object
}
}