ElaWorkshop / TagListView

Simple and highly customizable iOS tag list view, in Swift.
MIT License
2.64k stars 492 forks source link

Correctly calculate `intrinsicContentSize` before first layout run #215

Open andi357 opened 5 years ago

andi357 commented 5 years ago

This pull requests adds the ability to calculate the intrinsicContentSize of TagListView without requiring a full layout-run. This is for example the case if some one wants to pre-calculate the sizes of UICollectionViewCells (with systemLayoutSizeFitting (...)) that have a TagListView embedded.

In my case, the intrinsicContentSize was always wrong (height: number of tag x tag-height) because the tag list inside my static prototyping cell (which is used for size-pre-calculation) was not layouted yet. And since layouting the whole cell is more expensive then using systemLayoutSizeFitting() while gathering the correct cell sizes is critical for scrolling performance of the whole collection view, I had to find a way to calculate the intrinsicContentSize without that dependency from the view's frame.

BTW: Even Apples documentation for intrinsicContentSize says:

This intrinsic size must be independent of the content frame

My solution is inspired from UILabel's preferredMaxLayoutWidth, since multiline labels have the same requirement to calculate their height depending of their width, which they don't know prior layouting.

So in rearrangeViews() the TagListView uses the newly introduced preferredLayoutWidth property (if set to a proper value) for calculating the distribution of all tags (instead of frame.width). The getter of intrinsicContentSize then looks for the widest rowView to determine the tag list view's intrinsic width.

When using autolayout, the tag list view will then be sized based on it's intrinsicContentSize.

mikestalker commented 5 years ago

And how your solution will work for iPad and iPhone? Different preferredLayoutWidth?

andi357 commented 5 years ago

@mikestalker Yes, similar to UILabels preferredMaxLayoutWidth you need to set the value depending on the available space, which might be (but doesn't have to) different on iPhone and iPad.

Andreas409 commented 5 years ago

this saved me 🙏 thank you very much!