Reputation: 193
As you can see in the image below, I have a UICollectionViewCell that contains an UIImageView with a fixed-height image. Below the UIImageView there is a vertical UIStackView that contains all the labels and sub-stackviews with the title, price e.g.
The compositional layout section that results in the image's 2-column grid is this:
func createSection() -> NSCollectionLayoutSection {
// Layout configuration values
let cellHeight = CGFloat(205.0)
let sectionTopSpacing = CGFloat(12.0)
let sectionLeadingSpacing = CGFloat(12.0)
let sectionTrailingSpacing = CGFloat(12.0)
let sectionBottomSpacing = CGFloat(12.0)
let numberOfColumns = UIDevice.current.userInterfaceIdiom == .pad ? 4 : 2
let interItemSpacing = CGFloat(8.0)
let interGroupSpacing = CGFloat(8.0)
// Item
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(cellHeight))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
// Group
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(cellHeight))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
subitem: item,
count: numberOfColumns)
group.interItemSpacing = .fixed(interItemSpacing)
// Section
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = interGroupSpacing
section.contentInsets = NSDirectionalEdgeInsets(top: sectionTopSpacing,
leading: sectionLeadingSpacing,
bottom: sectionBottomSpacing,
trailing: sectionTrailingSpacing)
return section
}
I have tried several compression resistance and hugging priority values both for the vertical stack view and it's labels.
Any idea how I could make the items of the same group have the same height according to the group's tallest item would be more than welcome.
Thank you very much in advance!
Upvotes: 2
Views: 1220
Reputation: 1
Man, i've managed it with custom UICollectionViewCompositionalLayout subclass by adjusting the heights to max in layoutAttributesForItem(at indexPath: IndexPath). Also, if you have more than one section you need to adjust y-positions for their items too. For simplicity i will drop this part.
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let allAttributes = super.layoutAttributesForElements(in: rect)
return allAttributes?.compactMap { attributes in
switch attributes.representedElementCategory {
case .cell:
return layoutAttributesForItem(at: attributes.indexPath)
default:
return attributes
}
}
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = super.layoutAttributesForItem(at: indexPath)?.copy() as? UICollectionViewLayoutAttributes
guard let frame = attributes?.frame else {
return attributes
}
if frame.height > maxHeight {
maxHeight = frame.height
}
attributes?.frame.size = CGSize(
width: frame.width,
height: maxHeight
)
return attributes
}
private var maxHeight = CGFloat.zero
Upvotes: -1