NSLayoutConstraint defined in code and bottom Layout Guide deprecated in iOS 11

I have a viewController holding a constraint like this one:

self.subviewConstraint = NSLayoutConstraint(item: self.subviewConstraint,
                                                     attribute: .bottom,
                                                     relatedBy: .equal,
                                                     toItem: self.bottomLayoutGuide,
                                                     attribute: .bottom,
                                                     multiplier: 1,
                                                     constant: 0)

and I'm being shown this warning:

'bottomLayoutGuide' was deprecated in iOS 11.0: Use view.safeAreaLayoutGuide.bottomAnchor instead of bottomLayoutGuide.topAnchor

I'm only finding examples for setting anchors instead of NSLayoutConstraints like this, and I don't fully understand this warning... "use view.safeAreaLayoutGuide.bottomAnchor instead of bottomLayoutGuide.topAnchor"? How is that the bottom anchor of the safeAreaLayoutGuide matches the top anchor of the of the bottomLayoutGuide? Where could I find a good graphical explanation of this? How should I correctly rewrite my constraint to keep its current behaviour?

1 answer

  • answered 2019-02-23 18:28 Andrea Corsini

    TopLayoutGuide and bottomLayoutGuide are deprecated since iOS 11.

    You could update your code with this, taking advantage of the new NSLayoutAnchor:

    self.subviewConstraint = self.subviewConstraint?.firstItem?.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
    

    or you can use the initializer of NSLayoutConstraint as in your question:

    self.subviewConstraint = NSLayoutConstraint(item: self.subviewConstraint?.firstItem as Any,
                                                        attribute: .bottom,
                                                        relatedBy: .equal,
                                                        toItem: view.safeAreaLayoutGuide,
                                                        attribute: .bottom,
                                                        multiplier: 1,
                                                        constant: 0)
    

    Note that I've changed your self.subviewConstraint parameter to self.subviewConstraint.firstItem instead, within the NSLayoutConstraint initialization method, because you were using the NSLayoutConstraint as the item. I suppose this is some kind of typo you made.

    Here you can find some good graphical explanation of the new SafeArea behaviour in iOS 11 and above: iOS Safe Area - Medium.com

    Additionally, you said "I'm only finding examples for setting anchors instead of NSLayoutConstraints", but I want to make it clear that the constraint(equalTo:) method of NSLayoutAnchor returns an NSLayoutConstraint. (Apple NSLayoutAnchor documentation)