Background:
When rotating the device, the view myView
becomes letterboxed instead of resizing to fit the screen, see image below.
On the storyboard, centreX
and centreY
constraints are set.
In the code, width
and height
constraints are set with the function viewAddConstraints()
, see code below.
After the device is rotated, I call viewAddConstraints()
again, but Xcode gives the following error: Unable to simultaneously satisfy constraints.
Questions:
How do I correctly remove old constraints and then add new constraints when the device is rotated?
How do I correctly update the constraints of a view when the device is rotated?
Code:
func viewAddConstraints() {
// Width constraint full width of screen
let myViewWidth = NSLayoutConstraint(item: myView as Any, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: view.bounds.width)
myView.addConstraint(myViewWidth)
// Height constraint full height of screen
let myViewHeight = NSLayoutConstraint(item: myView as Any, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: view.bounds.height)
myView.addConstraint(myViewHeight)
}
Image:
Current situation, view is incorrectly letterboxed.
Intended situation, view resized correctly.
The proper way to set constraints to keep your subview "pinned" to the sides:
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = .systemTeal
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
NSLayoutConstraint.activate([
myView.topAnchor.constraint(equalTo: view.topAnchor),
myView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
myView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
myView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
Or, since you should be respecting the Safe Area:
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = .systemTeal
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
myView.topAnchor.constraint(equalTo: g.topAnchor),
myView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
myView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
myView.bottomAnchor.constraint(equalTo: g.bottomAnchor),
])
}
Now your subview will automatically resize to fit its superview on device rotation.