I've successfully been able to create a grid layout using UICollectionViewCompositionalLayout
. However, I am unable to find a clever way of ensuring the UICollectionViewCell
in each row in the grid are of the same height when their heights are dynamic. i.e. I want the cell to stretch to fill the available space height-wise in the row.
Desired layout:
+------+--+------+--+------+
|~~~~~~| |~~~~~~| |~~~~~~|
|~~~~~~| |~~~~~~| |~~~~~~|
|~~~~~~| |~~~~~~| | |
|~~~~~~| | | | |
-------- ------- -------- <--- divider
+------+--+------+--+------+
Note: The row itself is the correct height but I want the cell content to stretch to fill the available space because I need to insert a small "line-divider" at the bottom of each cell. I thought about using a supplementary view for this but it seemed sort of messy.
Current attempt:
func createLayout() -> UICollectionViewLayout {
let estimatedHeight: CGFloat = 100
let item = NSCollectionLayoutItem(
layoutSize: .init(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(estimatedHeight)),
supplementaryItems: []
)
let groupLayoutSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(estimatedHeight))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupLayoutSize, subitem: item, count: 3)
let section = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
section.interGroupSpacing = 10
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
Result:
+------+--+------+--+------+
|~~~~~~| |~~~~~~| |~~~~~~|
|~~~~~~| |~~~~~~| |~~~~~~|
|~~~~~~| |~~~~~~| --------
|~~~~~~| --------
--------
+------+--+------+--+------+
Sample code: https://github.com/johnliedtke/grid-layout
NSCollectionLayoutSupplementaryItem subclasses NSCollectionLayoutItem, so you should be able to add it as a subitem of your group. So you'd use
let item = NSCollectionLayoutItem(
layoutSize: .init(widthDimension: .fractionalWidth(1.0), heightDimension: .fractional(1))
)
let sup = NSCollectionLayoutSupplementaryItem(
layoutSize: .init(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(2)),
elementKind: "LineReusableView",
containerAnchor: .init(edges: [.bottom])
)
let threeItemGroup = NSCollectionLayoutGroup.horizontal(layoutSize: groupLayoutSize, subitem: item, count: 3)
let group = NSCollectionLayoutGroup.vertical(layoutSize: layoutGroupSize,subitems: [threeItemGroup,sup])
let section = NSCollectionLayoutSection(group: group)
This should result in you only having one line at the bottom of each group rather than your desired three lines, but you should be able to change how that looks in designing your supplementary view (making it draw 3 distinct lines rather than just 1).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With