title: Changing Auto Layout constant doesn't update its frame
body: <p>I've created a little info view I'd like to add as a subview to a UIVisualEffectView. On my info view I created a free form xib and used Auto Layout for all the UILabels and one UIButton. The goal here is that <strong>Start, Pull</strong> and <strong>Sled</strong> are all optional so if that data doesn't exist I want to collapse those UILabels. I've accomplished this by updating their <strong>equal height</strong> constraint to 0. </p>
  
  <p><strong>my  problem</strong> is when some or all of those optional UIlabels collapse I want to update the <code>UIView</code>'s frame's height so things are tidy and don't potentially have gaps.</p>
  
  <p><a href="https://i.stack.imgur.com/M2sSN.png" rel="noreferrer"><img src="https://i.stack.imgur.com/M2sSN.png" alt="enter image description here"></a></p>
  
  <p>I do the below to update the constraints I've tagged in IB.</p>
  
  <pre><code>    for view in self.view.subviews {
          for constraint in view.constraints {
              if let identity = constraint.identifier {
                  if labelTags.contains(identity) {
                      print("Before: \(view.frame)")
                      constraint.constant = labelHeight
                      view.setNeedsUpdateConstraints()
                      print("After: \(view.frame)")
                  }
              }
          }
      }
  
  Before: (5.0, 101.0, 50.0, 25.0)
  After: (5.0, 101.0, 50.0, 25.0)
  Before: (58.0, 101.0, 101.0, 25.0)
  After: (58.0, 101.0, 101.0, 25.0)
  Before: (5.0, 129.0, 39.0, 25.0)
  After: (5.0, 129.0, 39.0, 25.0)
  Before: (47.0, 129.0, 23.0, 25.0)
  After: (47.0, 129.0, 23.0, 25.0)
  Before: (5.0, 157.0, 45.0, 25.0)
  After: (5.0, 157.0, 45.0, 25.0)
  Before: (53.0, 157.0, 63.0, 25.0)
  After: (53.0, 157.0, 63.0, 25.0)
  </code></pre>
  
  <p>After the constraints are updated I attempt to determine the view's frame by loops the views subview and get the max height like so:</p>
  
  <pre><code>    var height:CGFloat = 0.0
      for v in self.view.subviews {
          if (v.frame.origin.y + v.frame.size.height) &gt; height {
              height = (v.frame.origin.y + v.frame.size.height)
          }
      }
  
      self.frame.size.height = height
  </code></pre>
  
  <p>On first load <strong>getting the new frame height doesn't work because the UILabels frames don't update after updating their constraints.</strong> Here is the kicker, the same code runs on orientation change and it works! When I rotate back to portrait all my <code>UILabels</code> are lined up nicely and the <code>UIView</code> is pulled up snuggly under the <code>UIButton</code>!</p>
  
  <p>Any direction would be greatly appreciated, I've been at this for two days. Thanks!</p>
  
  <p><strong>UPDATE:</strong> </p>
  
  <p><code>self.view.layoutIfNeeded()</code> was indeed the winner! In my case timing was everything.</p>
  
  <p>I have never have paid that close attention but the below appear to be more of a 'suggestion' to the OS where as <code>layoutIfNeeded()</code> is immediate.</p>
  
  <pre><code>self.view.setNeedsUpdateConstraints()
  self.view.setNeedsLayout()
  self.view.setNeedsDisplay()
  </code></pre>