'UICollectionViewCompositionalLayout header misalignment
I have created a custom layout based on UICollectionViewCompositionalLayout
that presents each section's items in a panel or card...
...here the blue area is a NSCollectionLayoutDecorationItem
that is passed to the section via its decorationItems
property. This background item has its own content insets that inset it from the collection view bounds (the grey area) and the section has its own content insets to inset it within the panel. The purple section is 3 full width items (cells).
This all works as expected.
However, when I try to add a header to each section using boundarySupplementaryItems
, the header (red) appears to ignore the section's content insets, but the section does size itself as though it's properly positioned...
...the header pins itself to the top of the section, but the section height increases by the height of the header + the insets.
Here is the code I'm using to generate the layout...
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44.0))
let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44.0))
let headerItem = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: "header", alignment: .top)
let panelBackgroundItem = NSCollectionLayoutDecorationItem.background(elementKind: "PanelBackground")
panelBackgroundItem.contentInsets = NSDirectionalEdgeInsets(top: 4.0, leading: 8.0, bottom: 4.0, trailing: 8.0)
let section = NSCollectionLayoutSection(group: group)
section.boundarySupplementaryItems = [headerItem]
section.contentInsets = NSDirectionalEdgeInsets(top: 11.0, leading: 15.0, bottom: 11.0, trailing: 15.0)
section.decorationItems = [panelBackgroundItem]
let configuration = UICollectionViewCompositionalLayoutConfiguration()
configuration.interSectionSpacing = 4.0
let layout = UICollectionViewCompositionalLayout(section: section, configuration: configuration)
layout.register(PanelBackgroundView.self, forDecorationViewOfKind: "PanelBackground")
Can anyone advise on how I can get the header to position itself properly – just above the first item in the section, and respecting the content insets that have been set?
Solution 1:[1]
One way to work around, you can set contentInset.top to zero and using UICollectionViewCompositionalLayoutConfiguration.interSectionSpacing. Then the sectionHeader gonna be right above the first cell, and we also can configure the spacing among sections.
Solution 2:[2]
@Rafael, I post the answer here because the comment doesn't allow enough characters. This is taken from WWDC 2019's advanced collectionView layout :
func createLayout() -> UICollectionViewLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(44))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44)), elementKind: SectionHeadersFootersViewController.sectionHeaderElementKind, alignment: .top)
header.contentInsets = NSDirectionalEdgeInsets(top: 20, leading: 0, bottom: 20, trailing: 0)
let footer = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44)), elementKind: SectionHeadersFootersViewController.sectionFooterElementKind, alignment: .bottom)
section.boundarySupplementaryItems = [header,footer]
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)
let config = UICollectionViewCompositionalLayoutConfiguration()
config.interSectionSpacing = 10
let layout = UICollectionViewCompositionalLayout(section: section, configuration: config)
return layout
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Mihozil |
Solution 2 |