UIView with manual dynamic height inside auto-layout hierarchy
Sometimes you need to implement a manual layout for the view, that can be used inside auto-layouted hierarchy. In my case I needed a flow layout inside a simple view, without UICollectionView
.
This view should have intrinsicContentSize
so it can work correctly inside some stack views or somewhere else with layout constraints.
But the problem is that you cannot have intrinsicContentSize
that depends on current width of the view.
To fix that we can add local variable preferredMaxLayoutWidth
the same as we have in UILabel
. And we will update it inside layoutSubviews
:
The only problem with this implementation, our view will not return correct size when method systemLayoutSizeFitting(size)
will by called, because after this call our view will only be called with intrinsicContentSize
method. So we cannot know which size
was passed to systemLayoutSizeFitting
and we will not be able to calculate appropriate width.
Solution that can be used a bit hacky. You need to inherit UILabel
and override textRect(forBounds)
method. This method will be called even after systemLayoutSizeFitting
so we can really calculate intrinsicContentSize
depends on the passed width.
That’s all. And don’t forget to call invalidateIntrinsicContentSize()
when your view internal data changed and you need to recalculate your textRect(forBounds)
.