title: Why calling setNeedsUpdateConstraints isn't needed for constraint changes or animations?
body: <h1>Readings:</h1>
  
  <p>From this <a href="https://stackoverflow.com/a/12664093/5175709">answer</a>:</p>
  
  <p>This is what the accepted answer suggests to animate your view changes:</p>
  
  <pre><code>_addBannerDistanceFromBottomConstraint.constant = 0
  
  UIView.animate(withDuration: 5) {
      self.view.layoutIfNeeded()
  }
  </code></pre>
  
  <p>Why do we call <code>layoutIfNeeded</code> when we <strong>aren't</strong> changing the frames. We are changing the constraints, so (according to this <a href="https://stackoverflow.com/questions/20305654/what-is-the-difference-between-all-these-auto-layout-update-methods-are-all-nec">other answer</a>) shouldn't we instead be calling <code>setNeedsUpdateConstraints</code>? </p>
  
  <p>Similarly this highly viewed <a href="https://stackoverflow.com/a/20927069/5175709">answer</a> says:</p>
  
  <blockquote>
    <p>If something changes later on that invalidates one of your
    constraints, you should remove the constraint immediately and call
    setNeedsUpdateConstraints</p>
  </blockquote>
  
  <h1>Observations:</h1>
  
  <p>I actually did try using them both.
  Using <code>setNeedsLayout</code> my view <strong>animates correctly to the left</strong></p>
  
  <pre><code>import UIKit
  
  class ViewController: UIViewController {
  
      override func viewDidLoad() {
          super.viewDidLoad()
      }
  
      @IBAction func animate(_ sender: UIButton) {
  
          UIView.animate(withDuration: 1.8, animations: {
              self.centerXConstraint.isActive = !self.centerXConstraint.isActive
              self.view.setNeedsLayout()
              self.view.layoutIfNeeded()
          })
      }
  
      @IBOutlet weak var centerYConstraint: NSLayoutConstraint!
      @IBOutlet var centerXConstraint: NSLayoutConstraint!
  }
  </code></pre>
  
  <p>However using <code>setNeedsUpdateConstraints</code> <strong>doesn't</strong> animate, It just moves the view <strong>rapidly to the left</strong>. </p>
  
  <pre><code>import UIKit
  
  class ViewController: UIViewController {
  
      override func viewDidLoad() {
          super.viewDidLoad()
      }
  
      @IBAction func animate(_ sender: UIButton) {
  
          UIView.animate(withDuration: 1.8, animations: {
          self.centerXConstraint.isActive = !self.centerXConstraint.isActive
              self.view.setNeedsUpdateConstraints()
              self.view.updateConstraintsIfNeeded()    
          })
      }        
  
      @IBOutlet weak var centerYConstraint: NSLayoutConstraint!
      @IBOutlet var centerXConstraint: NSLayoutConstraint!
  }
  </code></pre>
  
  <hr>
  
  <p>If I don't want animation then using either of <code>view.setNeedsLayout</code> or <code>view.setNeedsUpdateConstraints</code> move it to the left. However:</p>
  
  <ul>
  <li>with <code>view.setNeedsLayout</code>, after my button is tapped, my <code>viewDidLayoutSubviews</code> breakpoint is reached. But the <code>updateViewConstraints</code> breakpoint is never reached. This leaves me baffled as to how the constraints are getting updated...</li>
  <li>with <code>view.setNeedsUpdateConstraints</code>, after the button is tapped my  <code>updateViewConstraints</code> breakpoint is reached and <em>then</em> the <code>viewDidLayoutSubviews</code> breakpoint is reached. This does make sense, the constraints are updated, then the layoutSubviews is called.</li>
  </ul>
  
  <h1>Questions:</h1>
  
  <p>Based on my readings: if you change constraints then for it to become effective you MUST call <code>setNeedsUpdateConstraints</code>, but based on my observations that's wrong. Having the following code was enough to animate:</p>
  
  <pre><code>self.view.setNeedsLayout()
  self.view.layoutIfNeeded()
  </code></pre>
  
  <p>WHY?</p>
  
  <p>Then I thought maybe somehow under the hoods it's updating the constraints through other means. So I placed a breakpoint at <code>override func updateViewConstraints</code> and <code>override func viewDidLayoutSubviews</code> but only the <code>viewDidLayoutSubviews</code> reached its breakpoint.</p>
  
  <p>So how is the Auto Layout engine managing this?</p>