Search code examples
swiftios10ios11nslayoutconstraintsafearealayoutguide

NSLayoutConstraint and safeAreaLayoutGuide - coding compatible for pre-iOS 11


If I want an app compatible for pre-iOS 11 devices, do I need this code for each and every constraint that links some property of a view to self.view in order to abide by safeAreaLayoutGuide?

if #available(iOS 11.0, *) {
     NSLayoutConstraint.activate([
          theImage.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor, multiplier: 0.5)
          theImage.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),
          theImage.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -view.frame.width/8)
     ])
} else {
     NSLayoutConstraint.activate([
          theImage.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5)
          theImage.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20),
          theImage.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -view.frame.width/8),
     ])
}

Solution

  • That code looks right. If you're worried about having duplication all over the place, there are ways to consolidate it. You could do something like this:

    extension UIViewController {
    
        var correctLayoutGuide: UILayoutGuide {
            if #available(iOS 11.0, *) {
                return view.safeAreaLayoutGuide
            }
            else {
                return view.layoutMarginsGuide
            }
        }
    
    }
    

    Then your code snippet could just be:

    NSLayoutConstraint.activate([
          theImage.heightAnchor.constraint(equalTo: correctLayoutGuide.heightAnchor, multiplier: 0.5)
          theImage.bottomAnchor.constraint(equalTo: correctLayoutGuide.bottomAnchor, constant: -20),
          theImage.trailingAnchor.constraint(equalTo: correctLayoutGuide.trailingAnchor, constant: 20)
     ])