Reputation: 6477
I want to set a subview constraint as follows. If the interface is landscape (view.bounds.width > view.bounds.height),set aspect ratio of subview to be 4:3. In portrait mode, it should be 3:4. While I can always change the constraints programmatically on auto rotation, wondering if there is a clever way of designing constraints that is only one time.
Upvotes: 1
Views: 1119
Reputation: 1048
You'll have to listen for the UIDevice.orientationDidChangeNotification
notification like in this example:
class ViewController3: UIViewController {
let blueSubview: UIView = {
let view = UIView()
view.backgroundColor = .blue
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
var blueSubviewHeight = NSLayoutConstraint()
var blueSubviewWidth = NSLayoutConstraint()
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(refreshConstraints), name: UIDevice.orientationDidChangeNotification, object: nil)
refreshConstraints()
setUI()
}
fileprivate func setUI() {
view.backgroundColor = .white
view.addSubview(blueSubview)
[blueSubview.leftAnchor.constraint(equalTo: view.leftAnchor),
blueSubview.topAnchor.constraint(equalTo: view.topAnchor),
blueSubviewWidth,
blueSubviewHeight].forEach({ $0.isActive = true })
}
@objc func refreshConstraints() {
NSLayoutConstraint.deactivate([blueSubviewWidth, blueSubviewHeight])
if view.frame.width > view.frame.height {
blueSubviewWidth = blueSubview.widthAnchor.constraint(equalToConstant: view.frame.height * (4/3))
blueSubviewHeight = blueSubview.heightAnchor.constraint(equalToConstant: view.frame.height)
}
else {
blueSubviewWidth = blueSubview.widthAnchor.constraint(equalToConstant: view.frame.width)
blueSubviewHeight = blueSubview.heightAnchor.constraint(equalToConstant: view.frame.width * (4/3))
}
NSLayoutConstraint.activate([blueSubviewWidth, blueSubviewHeight])
}
}
Upvotes: 1