I have been trying to understand and utilize intrinsicSize
on a custom UIView
for some days now. So far with little success.
The post is quite long, sorry for that :-) Problem is, that the topic is quite complex. While I know that there might be other solutions, I simply want to understand how intrinsicSize
can be used correctly.
So when someone knows a good source for a in depth explanation on how to use / implement intrinsicSize
you can skip all my questions and just leave me link.
My goal:
Create a custom UIView
which uses intrinsicSize
to let AutoLayout automatically adopt to different content. Just like a UILabel
which automatically resizes depending on its text content, font, font size, etc.
As an example assume a simple view RectsView
which does nothing but drawing a given number of rects of a given size with given spacing. If not all rects fit into a single row, the content is wrapped and drawing is continued in another row. Thus the height of the view depends on the different properties (number of rects, rects size, spacing, etc.)
This is very much like a UILabel
but instead of words or letters simple rects are drawn. However, while UILabel
works perfectly I was not able to achive the same for my RectsView
.
Why intrinsicSize
I do not have to use intrinsicSize
to achieve my goal. I could also use subviews and add constraints to create such a rect pattern. Or I could use a UICollectionView
, etc.
While this might certainly work, I think it would add a lot of overhead. If the goal would be to recreate a UILabel
class, one would not use AutoLayout or a CollectionView to arrange the letters to words, would one? Instead one would certainly try to draw the letters manually... Especially when using the RectsView
in a TableView or a CollectionView a plain view with direct drawing is certainly better than a complex solution compiled of tons of subviews arranged using AutoLayout.
Of course this is an extreme example. However, at the bottom line there are cases where using intrinsicSize
is certainly the better option. Since UILabel
and other build in views uses intrinsicSize
perfectly, there has to be a way to get this working and I just want to know how :-)
My understanding of intrinsic Size
The problem is that I found no source which really explains it... Thus I have spend several hours trying to understand how to correctly use intrinsicSize
without little progress.
This is what I have learned [from the docs][1]:
intrinsicSize
is a feature used inAutoLayout
. Views which offer an intrinsic height and/or width do not need to specify constraints for these values.- There is no guarantee that the view will exactly get its
intrinsicSize
. It is more like a way to tell autoLayout which size would be best for the view while autoLayout will calculate the actual size. - The calculation is done using the
intrinsicSize
and theCompression Resistance
+Content Hugging
properties. - The calculation of the
intrinsicSize
should only depend on the content, not of the views frame.
What I do not understand:
- How can the calculation be independent from the views frame? Of course the
UIImageView
can use the size of its image but the height of aUILabel
can obviously only be calculated depending on its content AND its width. So how could myRectsView
calculate its height without considering the frames width? - When should the calculation of the
intrinsicSize
happen? In my example of theRectsView
the size depends on rect size, spacing and number. In aUILabel
the size also depends on multiple properties like text, font, font size, etc. If the calculation is done when setting each property it will be performed multiple times which is quite inefficient. So what is the right place to do it?
I will continue the question a second post due to the character limit...