Reputation: 32054
I have a UILabel
(the subtitle) that I want to have a static X origin, but extend to the edge of its nearest neighbor. There's a button ("Visit Link") that is optionally removed from the superview at runtime if not needed. The constraint from the label to the button has a priority of 1000, and the constraint from the label to the superview container has a priority of 250:
However, when I run the application removing the button (via .removeFromSuperview()
in the viewDidLoad
method), via the view debugging I see that the content size is setting the width of the label, taking priority over the constraint I have set.
I expect the label to extend to the edge of the view, but as you can see, the constraint is greyed out - I assume trumped by the (content size)
constraint instead:
Does the (content size)
constraint have a higher priority than my Trailing Space to: Superview
constraint? And how can I change it, since it's not a constraint I've even defined?
Upvotes: 3
Views: 554
Reputation: 3043
From the second screenshot, it looks like everything is working as it is supposed to.
Two things I'd like to mention:
To make this layout a bit more robust, I'd change the Trailing space of the label so that it has priority 1000
but is >= 0
.
This way, the layout will be valid with or without the Visit Link button and the content size of the label (it's intrinsic size) will resize it to whatever length it needs to be, but no more than the right edge of its superview.
Hope this helps!
UPDATE: Wrote a quick post on why this content size is appearing and why you should use it to your advantage.
Upvotes: 0
Reputation: 32054
The (content size)
constraint, automatically installed by the system at runtime, seems to have a priority somewhere between 250 and 750. When I use 250
or 251
for my Trailing Space
constraint, it does not work.
However, bumping the priority of my Trailing Space
constraint up to the Xcode-titled High priority of 750
, allows it to take precedence. So the defaults for the width of UILabel
seem to fall "somewhere in the middle."
Autolayout, you silly.
Upvotes: 0
Reputation: 90521
When you remove the button from the view hierarchy, that also removes any constraints involving the button. So, all that's left is the trailing constraint to the superview at priority 250.
The label has an intrinsic width based on its content. That means that its horizontal content hugging and compression resistance priorities come into play. Its content hugging priority is 251.
That means that it's more important to the auto layout system that the view's width be no larger than necessary than it is to keep its trailing edge at 8 points from the superview's trailing edge.
You should probably increase the priority of the trailing constraint. You want it to be less than the trailing constraint to the button so that, in the case where the button is present, it doesn't conflict. You also want it less than the button's compression resistance priority, so that the button doesn't get squished to allow the label to be 8 points from the superview. But, other than that, you want it to be as high as possible. (In the hypothetical case where you simply got rid of the possibility of there being a button, you would normally make that trailing constraint required, right? So, it should be as close as possible to required without causing undesirable side effects.)
If you're targeting deployment to iOS 9.0 or later, you should consider using a UIStackView
for this layout. It will take care of some things for you, like adding or removing the appropriate constraints when the button is hidden or shown.
Upvotes: 1