lencharest
lencharest

Reputation: 2935

Dynamic UILabel with proportional width and text-driven height

I'm trying to programmatically create a container view with two UILabel subviews which behave as follows:

I have defined the labels with numberOfLines = 0 and lineBreakMode = NSLineBreakByWordWrapping.

Note that the size of the container is completely dynamic; its width is determined by its superview, while its height is determined by its subviews (the labels). The size of the labels is also dynamic; their widths are proportional to the container width, and their heights depend on the length of the text.

I've been able to achieve everything above, except for the last item, with the following constraints (pseudo-code). A is the left label, B is the right.

The last 2 constraints are intended to stretch the container to fit the taller of the labels, but the layout engine seems to ignore the fact that the labels may be multiline. That is, I always get a single line displayed, no matter the length of the text.

So what constraints do I need to add/modify/delete in order to achieve the full set of behaviors described above?

Upvotes: 5

Views: 11280

Answers (3)

Geek
Geek

Reputation: 8320

Make sure you set

  1. horizontal and vertical content compression resistance priority. If you do not want label to truncate its content then set it to 1000.i.e. required.
  2. Content hugging priority. Look at this answer to understand how it works.

Upvotes: 0

Mark Kryzhanouski
Mark Kryzhanouski

Reputation: 7241

To make your labels automatically resize height you need to do following:

  1. Set layout constrains for label (That what you actually have done)
  2. Set height constraint with low priority. It should be lover than ContentCompressionResistancePriority
  3. Set numberOfLines = 0
  4. Set ContentHuggingPriority higher than label's hight priority
  5. Set preferredMaxLayoutWidth for label. That value is used by label to calculate its height

For example:

self.descriptionLabel = [[[UILabel alloc] init] autorelease];
self.descriptionLabel.numberOfLines = 0;
self.descriptionLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.descriptionLabel.preferredMaxLayoutWidth = 200;

[self.descriptionLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self.descriptionLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self.descriptionLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:self.descriptionLabel];

NSArray* constrs = [NSLayoutConstraint constraintsWithVisualFormat:@"|-8-[descriptionLabel_]-8-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)];
[self addConstraints:constrs];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[descriptionLabel_]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]];
[self.descriptionLabel addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[descriptionLabel_(220@300)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]];

Upvotes: 8

Sandeep Ankam
Sandeep Ankam

Reputation: 316

Set the priority of Height Constraints for the labels to low value and try setting the constraints in code.

Upvotes: 0

Related Questions