title: Changing Size Classes in Code (Swift)
body: <p>I’ve been trying to get up and running with building adaptive layouts in pure code (no storyboards used). I use layout anchors to set constraints and utilize traitCollectionDidChange method to vary between various sets of constraints and other interface changes. I use a switch statement to call the corresponding method with the corresponding set of constraints. </p>
  
  <pre><code>override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
      super.traitCollectionDidChange(previousTraitCollection)
  
      switch (traitCollection.horizontalSizeClass, traitCollection.verticalSizeClass) {
      case (.regular, .regular):
          setupRegularRegular()
  
      case (.compact, .compact):
          setupCompactCompact()
  
      case (.regular, .compact):
          setupRegularCompact()
  
      case (.compact, .regular):
          setupCompactRegular()
  
      default: break
      }
  
  }
  </code></pre>
  
  <p>For the sake of testing, I changed only one constraint, which is centerYAnchor.constraint. In portrait the constant is -150, in landscape I want it to be changed to 50. For iPad, I set the constant to 0.</p>
  
  <pre><code>bigLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -150).isActive = true
  </code></pre>
  
  <p>It works fine when switching between iPhone and iPad. However, if you start rotating the iPhone from portrait to landscape, the layout system fails, saying:</p>
  
  <pre><code>[LayoutConstraints] Unable to simultaneously satisfy constraints.
  Probably at least one of the constraints in the following list is one you don't want. 
  Try this: 
      (1) look at each constraint and try to figure out which you don't expect; 
      (2) find the code that added the unwanted constraint or constraints and fix it. 
  (
  "&lt;NSLayoutConstraint:0x600000097890 UILabel:0x7fac02c08aa0'Main Label'.centerY == UIView:0x7fac02e0a950.centerY - 150   (active)&gt;",
  "&lt;NSLayoutConstraint:0x604000097840 UILabel:0x7fac02c08aa0'Main Label'.centerY == UIView:0x7fac02e0a950.centerY + 50   (active)&gt;"
  )
  
  Will attempt to recover by breaking constraint 
  &lt;NSLayoutConstraint:0x604000097840 UILabel:0x7fac02c08aa0'Main Label'.centerY == UIView:0x7fac02e0a950.centerY + 50   (active)&gt;
  </code></pre>
  
  <p>I tried overriding various methods and setting the isActive property of the constraint to false and then back to true, but that didn’t help. I searched the web for a couple of days. No solution so far. So my question is, how do you actually switch between size classes the right way when rotating the device? Is it necessary to override any other method or something? Is there a better solution for adaptive layout in pure code? Are there any best practices when it comes to adaptive layouts / size classes / layout anchors and constraints in code (without using the storyboard)?
  Thanks for help!</p>
  
  <p>P.S. the methods setting up constraints are:</p>
  
  <pre><code>func setupCompactRegular() {
  
      bigLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -150).isActive = true
  
  }
  
  func setupRegularCompact() {
  
      bigLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 50).isActive = true
  
  }
  </code></pre>