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.
A vanilla UIView instance, for example, does not have an intrinsic content size. This means that you need to add four explicit constraints to describe the size and position of a UIView instance in a user interface.
In general, the intrinsic content size simplifies the layout, reducing the number of constraints you need. However, using the intrinsic content size often requires setting the view's content-hugging and compression-resistance (CHCR) priorities, which can add additional complications.
Intrinsic content size is information that a view has about how big it should be based on what it displays. For example, a label's intrinsic content size is based on how much text it is displaying. In your case, the image view's intrinsic content size is the size of the image that you selected.
Returns the optimal size of the view based on its current constraints.
Are you have aspect ratio constraint? systemLayoutSizeFitting doesn't work properly when there is aspect ratio constraint.
First, try to set height constraint instead of aspect ratio on image and if it works, set the height constraint constant = image.width * 1.33 in code
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