5
votes

I'm trying to understand how hugging and compression resistance really work.

I have this scenario where I need two labels on the left (inside the green container) and two labels on the right (inside the blue container).

enter image description here

As the image shows, I want the green container to hug content (Android's wrap content) and the blue container to fill the remaining space (Android's fill_parent).

I thought I could just add hugging/compression priorities to the green view, like:

greenView.setContentHuggingPriority(
    UILayoutPriorityDefaultHigh, forAxis: .Horizontal)
greenView.setContentCompressionResistancePriority(
    UILayoutPriorityDefaultHigh, forAxis: .Horizontal)

But it seems that it doesn't work as expected. I have to apply those constraints to the (red and yellow) labels instead.

Anyone knows the reason?

Some thoughts (edited):

From Ken's answer it follows that you have to set hugging/compression to the labels instead of container views.

In the example of this question, I would set, for example, a hugging of 750 (High) and a resistance of 1000 (Required) to the labels on the left. Since defaults for labels are hugging of 251 (Low+1) and resistance of 750 (High), the hugging and compression will be greater for the labels on the left (750 > 251 and 1000 > 750). At the same time, the compression will be greater than the hugging within the very labels (1000 > 750).

This way, the labels on the left will try to hug their content, but not as much as to compress it. For example, the red label can't wrap its content completely because the yellow label doesn't want to compress.

Phew!

1

1 Answers

19
votes

Content hugging and compression resistance priorities only have meaning in relation to the view's intrinsic content size. Basically, if a view has an intrinsic content width, then the auto layout system treats it as if it were subject to the following constraints:

[view(<=intrinsicWidth@contentHuggingPriority)]
[view(>=intrinsicWidth@compressionResistancePriority)]

That's all those mean. The same applies to the intrinsic height, too, of course.

A plain UIView used as a container has no intrinsic size. So, its content hugging and compression resistance priorities are meaningless.