title: How to programmatically add a UILabel with variable height and layout ios
body: <p>I have been searching for the whole day, but could not make it work.</p>
  
  <p>I have a <code>UIView</code> with two labels, on above the other, on the left side, and one button on the right side. I added the constraints to let <code>autolayout</code> resize views accordingly. Everything was working perfectly when I had set one constraint for the height of the <code>UIView</code> (and no one constraint for the height of the two <code>UILabel</code>), but as the content of the lower <code>UILabel</code> will vary, I removed that constraint and set two constraints for the <code>UILabel</code>, one fixed for the upper <code>UILabel</code> and one with relation "greater than or equal" for the lower <code>UILabel</code>, and other one to fix the distance between the lower <code>UILabel</code> and the <code>UIView</code>.</p>
  
  <p>It looks like auto layout is not capable of calculate the <code>intrinsicContentSize</code> of the lower <code>UILabel</code>, because it never increases its height above 10px, despite the content of the lower <code>UILabel</code>.</p>
  
  <pre><code>UIView *miView = [[UIView alloc] init];
  UILabel *miLabel = [[UILabel alloc] init];
  [miLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
  [miDetailsLabel setNumberOfLines:1];
  [miDetailsLabel setText:@"Just one line."];
  [miView addSubview:miLabel];
  UILabel *miDetailsLabel = [[UILabel alloc] init];
  [miDetailsLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
  [miDetailsLabel setNumberOfLines:0];
  [miDetailsLabel setText:@"Enough text to show 3 lines on an IP4, except first of three UILabels on my test code, with no content"];
  [miView addSubview:miDetailsLabel];
  UIButton *miButton = [[UIButton alloc] init];
  [miButton setTranslatesAutoresizingMaskIntoConstraints:NO];
  [miView addSubview:miButton];
  
  NSArray *constraint_inner_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[label]-(10)-[button(52)]-(0)-|" options:0 metrics:nil views:@{@"label":miLabel, @"button":miButton}];
  NSArray *constraint_inner2_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[details]-(10)-[button]-(0)-|" options:0 metrics:nil views:@{@"details":miDetailsLabel, @"button":miButton}];
  NSArray *constraint_label_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(0)-[label(18)]-(2)-[details(&gt;=10)]-(0)-|" options:0 metrics:nil views:@{@"label":miLabel, @"details":miDetailsLabel}];
  NSArray *constraint_button_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button(22)]" options:0 metrics:nil views:@{@"button":miButton}];
  [miView addConstraint:[NSLayoutConstraint constraintWithItem:miButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:miView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
  [miView addConstraints:constraint_inner_h];
  [miView addConstraints:constraint_inner2_h];
  [miView addConstraints:constraint_label_v];
  [miView addConstraints:constraint_button_v];
  </code></pre>
  
  <p>I ve put a reduced version of the code.</p>
  
  <p>any ideas of what I am missing?</p>
  
  <p>Thanks</p>
  
  <p>UPDATE : Thanks to Matt advice, I've tried this solution to set the proper value to <code>preferredMawLayoutWidth:</code></p>
  
  <pre><code>- (void)viewDidLayoutSubviews {
      [super viewDidLayoutSubviews];
  
      NSArray *allKeys = [dictOpcionesTickets allKeys];
      for (NSString *key in allKeys) {
          NSArray *tmpArray = [dictOpcionesTickets objectForKey:key];
          if (![[tmpArray objectAtIndex:0] isEqual:@""]) {
              UILabel *tmpLabel = [tmpArray objectAtIndex:3];
              tmpLabel.preferredMaxLayoutWidth = tmpLabel.frame.size.width;
              NSLog(@"width: %f",tmpLabel.frame.size.width);
          }
      }
      [self.view layoutIfNeeded];
  }
  </code></pre>
  
  <p>To explain the code, as I said, I'm doing it dynamically, so I've created a dictionary with an array with the references to my <code>UILabel</code> (among other interesting information). When I run the code, I get the next log (with the code parsing 3 <code>UILabel</code>, first label with no content):</p>
  
  <pre><code>2014-12-28 20:40:42.898 myapp[5419:60b] width: 0.000000
  2014-12-28 20:40:42.912 myapp[5419:60b] width: 0.000000
  2014-12-28 20:40:43.078 myapp[5419:60b] width: 229.000000
  2014-12-28 20:40:43.080 myapp[5419:60b] width: 229.000000
  2014-12-28 20:40:43.326 myapp[5419:60b] width: 229.000000
  2014-12-28 20:40:43.327 myapp[5419:60b] width: 229.000000
  </code></pre>
  
  <p>But I'm still getting the same result...the UIView is still showing a height equals to the minimum height set by the constraints, not showing the content of the <code>UILabel</code>.</p>
  
  <p>UPDATE 2 Still fooling around.</p>
  
  <p>I've tested my initial code but simplified on a fresh project in xcode 6, running on an actual iPhone 4 with iOS7, and it worked perfectly without setting <code>preferredMaxLayoutWidth</code> or subclassing <code>UILabel</code>, and even without calling <code>layoutIfNeeded</code> on parent view. But when it comes to the real project (I think it was originally builded in xcode 4 or 5) it does not work:</p>
  
  <pre><code>- (void)addLabelsDinamically {
      self.labelFixed.text = @"Below this IB label goes others added dinamically...";
  
      UIButton *miBoton = [[UIButton alloc] init];
      miBoton.translatesAutoresizingMaskIntoConstraints = NO;
      [miBoton setTitle:@"Hola" forState:UIControlStateNormal];
      [self.viewLabels addSubview:miBoton];
      [self.viewLabels addConstraint:[NSLayoutConstraint constraintWithItem:miBoton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.viewLabels attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
      [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[boton(22)]" options:0 metrics:nil views:@{@"boton":miBoton}]];
      [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[boton(40)]" options:0 metrics:nil views:@{@"boton":miBoton}]];
  
      UILabel *miLabel = [[UILabel alloc] init];
      miLabel.translatesAutoresizingMaskIntoConstraints = NO;
      miLabel.backgroundColor = [UIColor redColor];
      miLabel.numberOfLines = 0;
      miLabel.text = @"ñkhnaermgñlkafmbñlkadnlñejtnhalrmvlkamnñnañorenoetñnngñsdbmnñgwn";
      [self.viewLabels addSubview:miLabel];
      [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[label]-(10)-[boton]-(8)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]];
      [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(8)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":self.labelFixed}]];
      UIView *pre = miLabel;
  
      miLabel = [[UILabel alloc] init];
      miLabel.translatesAutoresizingMaskIntoConstraints = NO;
      miLabel.backgroundColor = [UIColor greenColor];
      miLabel.numberOfLines = 0;
      miLabel.text = @"ñkhnaermgñlkafmbñlkadnlñejtnhalrmvlkamnñnañorenoetñnngñsdbmnñgwn";
      [self.viewLabels addSubview:miLabel];
      [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[label]-(10)-[boton]-(8)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]];
      [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(8)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":pre}]];
  }
  </code></pre>
  
  <p>Ah, on the same screen I have one <code>UILabel</code> added on IB, with <code>numberOfLines</code> set to '0', vertical constraint "greater or equal than" and horizontal constraint set in a similar way (but both constraints set on IB)...and it works perfectly...this is driving me nuts!! any help???</p>