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
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
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
20pxon both sides. This was assigned a low priority of
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
400pxon 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