Nicoli
Nicoli

Reputation: 914

Swift changing constraints depending on device orientation

When the device is rotated from portrait to landscape, the width constraint of the view is updated but it does not update when the device is rotated from landscape to portrait

My code:

override func viewDidLoad() {
    super.viewDidLoad()
    theView.translatesAutoresizingMaskIntoConstraints = false
    theView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
    theView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
    theView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
    theView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
  }

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {

When the device is first rotated from portrait to landscape 'theView' width get the 50% of the view width

    if UIDevice.current.orientation.isLandscape {  
       theView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.50).isActive = true

Rotating from landscape to portrait does not restore the original width

    } else {
       theView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1.00).isActive = true
    }   
}

Here is an image that shows what I am trying to do.

enter image description here

Upvotes: 3

Views: 3697

Answers (1)

Kamil Szostakowski
Kamil Szostakowski

Reputation: 2163

You should disable right anchor constraint when rotating.

Because constraint method of the NSLayoutAnchor class always returns the new, inactive constraint you should keep the reference to the constraints you want to activate/deactivate.

The initialization may look like this.

override func viewDidLoad() {
    super.viewDidLoad()
    // ...        
    widthConstraint = theView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.50)
    rightConstraint = theView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0)
    rightConstraint.isActive = true
}

Having these references you can implement your willRotate: method like this.

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.current.orientation.isLandscape {
        rightConstraint.isActive = false
        widthConstraint.isActive = true
    }
    else {
        rightConstraint.isActive = true
        widthConstraint.isActive = false
    }
}

It should look like this.

Ilustration of the solution

Upvotes: 9

Related Questions