Autolayout to size views on different devices
Recently I ran into a not so interesting auto layout problem. I wanted to show a view which would stretch to the full width of iPhone with fixed padding like this
However, I also wanted to display the same view on iPad. But not stretching to the full device width. If it's an iPad device, I wanted to constrain its width to fixed size so as not to make it look ugly like this
Actual:
Of course I would've added an if-else
statement to check if device was iPad or iPhone. But in my opinion that was an ugly hack rather than having to use power of NSLayoutConstraint
and priority
associated with them.
In order to make the view work on both devices without need of if-else
, I added two constraint with varied priority.
- First one was to stretch the view to superview's full width with fixed padding of
20px
on both sides. This was assigned a low priority of999
units
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .red
self.view.addSubview(view)
let views = ["view": view]
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-100-[view(44)]", options: [], metrics: nil, views: views))
self.view.addConstraint(NSLayoutConstraint(item: view, attribute: .centerX, relatedBy: .equal, toItem: self.view, attribute: .centerX, multiplier: 1.0, constant: 0))
// First horizontal constraint with low priority
let minorWidthConstraint = NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: self.view.frame.width - 40)
minorWidthConstraint.priority = 999
self.view.addConstraint(minorWidthConstraint)
- Second one was to limit the maximum width of view to
400px
on any device. This constraint was setup with required priority of 1000 units
let majorWidthConstraint = NSLayoutConstraint(item: view, attribute: .width, relatedBy: .lessThanOrEqual, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 400)
majorWidthConstraint.priority = 1000
self.view.addConstraint(majorWidthConstraint)
Just as I expected, when the view was being displayed on iPad, second constraint with higher priority kicked in and limit the maximum width of view to 400px
preventing it from extending near the edges.
Result on iPad was with view constrained to its maximum width as follows.
Hope this small trick will help you anytime with auto layout adventures.
If you have any questions/queries/concerns, do not hesitate to write in comment section. You can also message me directly on the Twitter