0

I've just asked a question about changing a UIView height with proportional constraint. The problem was that I should have been using activate and deactivate for the constraints. This works fine once, but I want to toggle between two constraints.
I have a UIView called topView and two constraints:

  @IBOutlet var cHtTopView1: NSLayoutConstraint!  
  @IBOutlet var cHtTopView2: NSLayoutConstraint!

The first one scales the UIView to 0.3 times the height of the superview, the second to 0.5. This works once:

  @IBAction func buttonTouchUpInside(_ sender: Any) {
      NSLayoutConstraint.deactivate([self.cHtTopView1])
      NSLayoutConstraint.activate([self.cHtTopView2])
  }

However, if I have another button that tries to activate cHtTopView1 it gives an error. I'm pretty sure this is because the constraint is deleted from code. So, I then tried this:

  @IBAction func buttonTouchUpInside(_ sender: Any) {
      self.topView.removeConstraint(self.cHtTopView1)
      self.topView.addConstraint(self.cHtTopView2)
  }

This gives an error at .addConstraint. Not sure why this is - any help greatly appreciated. Thanks, Ian

Ian
  • 109
  • 2
  • 10
  • What is the error? – Paulw11 Mar 31 '19 at 03:48
  • @Paulw11, It goes to class AppDelegate: UIResponder, UIApplicationDelegate { and says 'Terminating with uncaught exception of type NSException.' And this: Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. – Ian Mar 31 '19 at 04:00
  • I've sorted it out! I have to add the constraint to the superview. Since this is called 'view' it should be @IBAction func buttonTouchUpInside(_ sender: Any) { self.view.removeConstraint(self.cHtTopView1) self.view.addConstraint(self.cHtTopView2) } – Ian Mar 31 '19 at 04:18
  • ps - code not formatted, but should be clear... – Ian Mar 31 '19 at 04:19
  • You said 'However, if I have another button that tries to activate cHtTopView1 it gives an error.' what is the error here? – Mohanad Refaai Mar 31 '19 at 05:29
  • @MohanadRefaai The problem here is that both constraints were created when the application is launched. I can deactivate one - the one that has priority - and then the other one comes into play. However, if I then try to activate the one that is deactivated, using the second button, it gives the error, since deactivate actually removes it from the view. Rather than use activate and deactivate, to toggle the constraints, you need to use removeConstraint and addConstraint. However, these are added/removed to the superview, in my case just the default main 'view'. – Ian Mar 31 '19 at 06:08
  • check this question, it may help https://stackoverflow.com/questions/27494542/when-can-i-activate-deactivate-layout-constraints – Mohanad Refaai Mar 31 '19 at 07:03
  • Just a heads up when you deactivate a constraint it is not deleted in anyway it's just not active. You can activate it again at another time fine. – Upholder Of Truth Mar 31 '19 at 09:46
  • Thanks @UpholderOfTruth - yes, I used the wrong terminology. The key for me was realising which view to apply the constraint to. – Ian Mar 31 '19 at 09:54

0 Answers0