5

I am trying to position a UILabel instance label next to a UITextField instance textfield like done in the iOS Settings dialogs. I'm using Auto Layout and constraints with the help of Florian Kuglers FLKAutoLayout extensions (https://github.com/dkduck/FLKAutoLayout).

enter image description here

When I set only a leading constraint for the label and a space constraint between label and textfield, the label and textfield widths are adjusted to their content. (bottom picture)

But when I set also a trailing constraint for the textfield, only textfields width is adjusted to its content, but label is stretched. (top picture)

I want to behave the opposite around, so that the textfield will be stretched and the label is adjusted to its content. Why does iOS decide to stretch the label instead of the textfield?

[self addSubview:self.label];
[self addSubview:self.textField];

[self.label alignLeadingEdgeWithView:self predicate:@"10"];
[self.textField constrainLeadingSpaceToView:self.label predicate:@"10"];

// difference between top and bottom pciture
// [self.textField alignTrailingEdgeWithView:self predicate:@"-25"];
matths
  • 760
  • 9
  • 19
  • set fix width of `UILabel` `[self.label constrainWidth:@"==40" height:@"==20"];` – Rahul Mane Sep 17 '13 at 09:31
  • but I don't want it to be fixed. I want it to adapt to the labels content, just as it does, and give the space left to the textfield instead. It's just that in my example first name and last name are equal of with, but there might be other labels as well. So working with a fixed width constraint is not the answer. :( – matths Sep 17 '13 at 09:34

2 Answers2

15

enter image description here

EDITED: So after the comment of Rahul I played with width and priorities. Adding the following width constraint lead into the somewhat wrong direction, because of entering some very long value, the label was resized too small.

[self.label constrainWidth:@"0@1"];

enter image description here

So I finally read up on "Compression Resistance and Content Hugging" (http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html) and the solution is to set the Horizontal Content Hugging priority of the label to a higher value.

[self.label setContentHuggingPriority:500 forAxis:UILayoutConstraintAxisHorizontal];

Then even entering big values will let the label stay as width as its content!

Solution is not adding a width constraint with priority, but to set Compression Resistance and Content Hugging properties for the intrinsic content size of the UIViews.

enter image description here

matths
  • 760
  • 9
  • 19
  • 1
    Good work. You should take a look at the priority meanings. You can change the priority up and down by one (i.e. 499, 500, 501) to make them effective. You can then use the constants and use... (UILayoutPriorityRequired - 1) etc... https://developer.apple.com/library/ios/documentation/AppKit/Reference/NSLayoutConstraint_Class/NSLayoutConstraint/NSLayoutConstraint.html – Fogmeister Sep 17 '13 at 12:16
  • Yep, I use content hugging especially for labels and buttons that "want" to take the space of a text field. I don't know why sometimes they grow and sometimes the stay at their intrinsic size. The behaviour is not always the same. For example, with `[label][field][button]` the `label` was too big but the button was small, and with `[field][button]` the button wanted to grow. A mystery. – Ferran Maylinch May 26 '15 at 00:00
0

Following constraints which I set in the storyboard works exactly how you want.

  • Horizontal space constraint between label and superview.(default)
  • Horizontal space constraint between textfield and superview. (default)
  • Horizontal space constraint between textfield and label.
Prasad Devadiga
  • 2,573
  • 20
  • 43
  • I'm doing everything by code. It might be that you specify a width for the label in Storyboard? – matths Sep 17 '13 at 11:24