0

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),
     ])
}
RanLearns
  • 4,086
  • 5
  • 44
  • 81

1 Answers1

5

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)
 ])
Connor Neville
  • 7,291
  • 4
  • 28
  • 44
  • 1
    Up voted. Was in the middle of a wordier answer saying the same thing. Don't forget about the pros/cons of extending `UIView` instead. –  Feb 22 '18 at 22:00
  • The extension looks great. Thanks! Regarding your "EDIT" point - trailingAnchor does not seem to conform to (equalTo: multiplier:). "Argument labels '(equalTo:, multiplier:)' do not match any available overloads." The constant on this constraint does correctly place the object using the frame math when ran in viewDidLoad – RanLearns Feb 22 '18 at 22:16
  • Huh, okay. If it's working for you, feel free to disregard! – Connor Neville Feb 22 '18 at 22:17