Search code examples
iosautolayoutvisual-format-language

When do you need content hugging for labels and buttons to prevent them from taking the space of a text field?


I am puzzled with a simple layout created programmatically, where you have a UILabel, a UITextField and a UIButton in a row using constraints. I hope you can help me understand the following behaviour.

If I use visual format language to lay out those views like this...

|-[label]-[field]-[button]-|

...I see that the label wants to take as much space as possible, like this:

[   label  ] [field] [button]

But if I remove the label from the equation...

|-[field]-[button]-|

...then it's the button who wants to take over the space:

[field] [       button      ]

By setting a "high hugging priority" to the label and button I can control their size (they keep their intrinsic size, I guess). But I don't know why the differences in behaviour in these cases.

Do you know how is autolayout exactly working here?

Related question:

Using Auto Layout to have UILabel and UITextField next to each other


Solution

  • When the content-hugging priorities of the label and the button are equal to each other, and one of them needs to be stretched to satisfy other constraints, then it is arbitrary which is stretched. In general, when there are multiple solutions to the constraints and the priorities don't distinguish them, there is ambiguity and the auto layout system can resolve the constraints in any of the possible solutions. It can change from run to run. It can even change each time the layout pass is done, which means views can jump around while the user interacts with them.

    The fact that in one case the label was stretched and in the other the button was is just random.

    When you have something like |-[label]-[field]-[button]-| and there's any chance that the width of the container will not always equal the sum of the intrinsic widths of the three views and the spacing between them (so that something may need to be stretched), you should always designate one to be stretched by making its content-hugging priority lowest.