Reputation: 21967
Consider the following desired layout. Note that this is not a "layout string" but a proxy for a picture. So | = superview edges, - = space, [xxx] = a view.
|--[label1]--[label2--------------]--[button]--|
The above layout is what I'm trying to achieve. In english:
label1
sized to fit content and is padded from the edge of the superviewlabel2
is padded from the edge of label1
and expands/contracts based on available horizontal spacebutton
is sized to fit content and is padded from the edge of label2
and the right edge of the superviewI hope this is clear. My current constraint is defined as:
[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-8-[label1]-4-[label2]-4-[button]-8-|"
options:0
metrics:nil
views:views];
This results in the following layout:
|--[label1----------------------]--[label2]--[button]--|
Question: how can I modify the constraint so label2
is proportionally sized and label
and button
are sized to fit content?
If it helps, here is equivalent code to create the constraints generated by the above sample.
NSLayoutConstraint *c1 = [NSLayoutConstraint
constraintWithItem:self.label1
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeLeading
multiplier:1.0f
constant:8.0f];
NSLayoutConstraint *c2 = [NSLayoutConstraint
constraintWithItem:self.label2
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.label1
attribute:NSLayoutAttributeTrailing
multiplier:1.0f
constant:4.0f];
NSLayoutConstraint *c3 = [NSLayoutConstraint
constraintWithItem:self.button
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.label2
attribute:NSLayoutAttributeTrailing
multiplier:1.0f
constant:4.0f];
NSLayoutConstraint *c4 = [NSLayoutConstraint
constraintWithItem:self
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.button
attribute:NSLayoutAttributeTrailing
multiplier:1.0f
constant:8.0f];
Upvotes: 1
Views: 3878
Reputation: 21967
@ilya's answer is a partial solution. It does keep label1
from expanding but label2
can still extend into the area I wanted button
to be in and `button can be compressed. After some trial and error and reading all the docs, I've found a better, and more appropriate solution. Been fun learing auto layout.
Rather than specifying a minimum width for label1
, which is somewhat artificial and also leaves other problems depending on view content, a better solution is to set the contentCompressionResistancePriority
and the contentHuggingPriority
for all views.
The constraints as shown in my question work perfectly as long as I also add the following:
[self.label1
setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh
forAxis:UILayoutConstraintAxisHorizontal];
[self.label1
setContentHuggingPriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisHorizontal];
[self.label2
setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisHorizontal];
[self.label2
setContentHuggingPriority:UILayoutPriorityDefaultHigh
forAxis:UILayoutConstraintAxisHorizontal];
[self.button
setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh
forAxis:UILayoutConstraintAxisHorizontal];
[self.button
setContentHuggingPriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisHorizontal];
Upvotes: 5
Reputation: 18816
Just add another constraint for width of label1
to equal some minimum size (e.g. in the interface builder when you add width constraint it will use current width automatically) but set its priority to be lower.
Upvotes: 1