Search code examples
iosswiftuiviewautolayout

Why does intrinsicContentSize for UIView always return (-1.0, -1.0)?


A UIView with proper autolayout is not returning a correct intrinsic content size. I am getting (-1.0, -1.0) even though I can see that it is sized correctly both in the storyboard and when the app runs.

I have tried creating a Playground that creates a UIView (a) and a UILabel. I add my label as a subview of (a) and set left, right, top, bottom constraints. I also set some text and verified that my label has a correct intrinsic size (which it does). My (a) view returns (-1.0, -1.0) for intrinsic content size.

I have also tried creating a new project with a storyboard. I added a UIView (a) to my view and centered it (X and Y). I added a UILabel to my (a) view and constrained left, right, top, bottom. I can see that the (a) view sizes correctly. When I run the app I see that it is still properly sized. My (a) view returns (-1.0, -1.0) for intrinsic content size.

I find this extremely strange considering that the UIView does layout according to its intrinsic content size (i.e. the subviews and associated constraints).

Assuming that my labels constraints to the edges of my (a) view are all distances of 0, then I would expect my (a) view to have an intrinsic content size equal to that of my label's frame (which is based on the intrinsic size of the label, but that is kinda moot).

I genuinely don't understand how a view can set its frame equivalent to the intrinsic size of its subelements while not having an intrinsic content size.

(The frame of (a) view returns the correct size, but that doesn't really answer my question. Also - it isn't helpful for my particular situation, but that is outside the scope of this question.)


Solution

  • I find this extremely strange considering that the UIView does layout according to its intrinsic content size (i.e. the subviews and associated constraints).

    This is just a misunderstanding of what the "intrinsic content size" is. An ordinary UIView has no (meaningful) instrinsic content size.

    The intrinsic content size is a property that some interface objects implement (such as UILabel and UIButton) so that you do not have give them height and width constraints. These are special interface objects that contain text (and/or, in the case of a button, an image), and can size themselves to fit that.

    Your UIView isn't like that, and basically doesn't implement the intrinsic content size at all. It is possible to write a UIView subclass that does implement the intrinsic content size, behaving like a UILabel or a UIButton; but you have not done so.


    You say in a comment:

    If I have a UIView with only a Center X and Center Y constraint and given it has some contents, I would like to know what its size is after autolayout operates

    Fine, but that is not its intrinsic content size. It is its size. If you are in the view controller, implement didLayoutSubviews and look at this view's bounds.size. That is the size you are after.

    I'm curious how I could calculate this

    Ah, ok. But then you should have asked that. The answer is: call systemLayoutSizeFittingSize.