Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

systemLayoutSizeFitting ignoring layout constraints and using image view intrinsic size

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.

like image 268
Nuno Gonçalves Avatar asked Jun 28 '17 11:06

Nuno Gonçalves


People also ask

Does Uiimageview have intrinsic content size?

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.

How does a view's intrinsic content size aid in auto layout?

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.

What is intrinsic content size?

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.

What is Systemlayoutsizefitting?

Returns the optimal size of the view based on its current constraints.


1 Answers

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

like image 54
iamirzhan Avatar answered Oct 17 '22 16:10

iamirzhan