When i was trying to create layout constraints, i read about NSLayoutAnchor class. They said:
Note
UIView does not provide anchor properties for the layout margin attributes. Instead, the layoutMarginsGuide property provides a UILayoutGuide object that represents these margins. Use the guide’s anchor properties to create your constraints
Ok. But simultaneously I crated anchor properties for the layout margin properties without UILayoutGuide property.
let inputsContainerView = UIView()
inputsContainerView.backgroundColor = UIColor.white
inputsContainerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(inputsContainerView)
//need x,y,width,height constraints
inputsContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
inputsContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0).isActive = true
inputsContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
inputsContainerView.heightAnchor.constraint(equalToConstant: 150).isActive = true
So then why do we need UILayoutGuide object? And it turns out UIView does provide anchor properties for the layout margin attributes? Please if someone know anything I would very appreciated.
It depends on your design requirements.
layoutMarginsGuide
documentation states:
A layout guide representing the view’s margins. Use this layout guide’s anchors to create constraints with the view’s margin.
Where Layout Margins is basically just the safe area of a view:
Safe areas help you place your views within the visible portion of the overall interface. UIKit-defined view controllers may position special views on top of your content. For example, a navigation controller displays a navigation bar on top of the underlying view controller’s content. Even when such views are partially transparent, they still occlude the content that is underneath them.
For self.view
, the visible portion of the overall interface would exclude the areas taken up by status bar, navigation bar, tab bar, etc.
For a normal UIView
, the default padding is 8px.
So basically, if you want someView
to be constrained within the safe area / margin of otherView
, then you will reference otherView
's layoutMarginsGuide
anchors.
If not, then just otherView
's anchors are enough.
layoutMarginsGuide
):let textField = UILabel()
textField.text = "Using Layout Margins Guide Anchors"
textField.backgroundColor = UIColor.red
textField.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(textField)
var constraints = [NSLayoutConstraint]()
//textfield's top edge = self.view's margin's top edge
constraints.append(textField.topAnchor.constraint(equalTo: self.view.layoutMarginsGuide.topAnchor))
//textfield's leading edge = self.view's margin's leading edge
constraints.append(textField.leadingAnchor.constraint(equalTo: self.view.layoutMarginsGuide.leadingAnchor))
//textfield's trailing edge = self.view's margin's trailing edge
constraints.append(textField.trailingAnchor.constraint(equalTo: self.view.layoutMarginsGuide.trailingAnchor))
//Apply the constraints
NSLayoutConstraint.activate(constraints)
Output:
Observation:
self.view
's left/right edgesself.view
's safe area / layout marginslayoutMarginsGuide
):let textField = UILabel()
textField.text = "Without Layout Margins Guide Anchors"
textField.backgroundColor = UIColor.red
textField.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(textField)
var constraints = [NSLayoutConstraint]()
//textfield's top edge = self.view's top edge
constraints.append(textField.topAnchor.constraint(equalTo: self.view.topAnchor))
//textfield's leading edge = self.view's leading edge
constraints.append(textField.leadingAnchor.constraint(equalTo: self.view.leadingAnchor))
//textfield's trailing edge = self.view's trailing edge
constraints.append(textField.trailingAnchor.constraint(equalTo: self.view.trailingAnchor))
//Apply the constraints
NSLayoutConstraint.activate(constraints)
Observation:
self.view
's left/right edgesself.view
's top edge which overlaps the status bar
self.view
's boundsFinally, it depends on your requirement.
Sometimes you should use it, sometimes you could use it, sometimes you just don't need to use it.
PS: Now, whether you base it on the UIView
's anchors or it's layoutMarginsGuide
anchors, it will respond to device rotation or any other layout changes automatically.