I'm using a custom layout for a UICollectionView
. My cell should have fixed width and flexible height.
The cell is composed of a UImageView
and a UIStackView
. The UIImageView
's constraints are the following:
image.top = cell.top
image.width = cell.width
image.height = image.width * 1.33
image.centerX = cell.centerX
image.bottom = stackView.top
The stack view is similar, and is indeed tied to the bottom of the cell.
When the system is calling preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
I'm performing some calculations to get the height of the cell.
let preferredAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)
let size = CGSize(width: layoutAttributes.frame.width,
height: UILayoutFittingCompressedSize.height)
let preferredSize = systemLayoutSizeFitting(size,
withHorizontalFittingPriority: .defaultHigh,
verticalFittingPriority: .fittingSizeLevel)
It turns out that the preferredSize is being calculated using the imageView instrinsic size rather than respecting the constraints. So for a image with 850x850, (and a cell with 160 points of width) I'm getting a much higher height than what I expect and therefore a cell with a huge space to the bottom.
I managed to solve this problem with something that I feel like it's a hack.
I created a reference to the width constraint of the image, update it when I call this method with the fixed value that I get from layoutAttributes and call setNeedsLayout() and layoutIfNeeded() and this works. But I really don't like that I have to force the layout to be done again and update the width myself, not to mention that I loose performance.
How can this be done in a better way?
Thank you very much.