Back in 2013 Apple introduced layout guides as part of the iOS 7 auto-layout. The topLayoutGuide and bottomLayoutGuide are properties of UIViewController and help you to safely align your view in the root view. Apple pays attention that your view doesn't clip behind the status bar or navigation bar and thereby only uses the safe layout area. These two layout guides are now deprecated.

With the release of iOS11, Apple introduced new layout guides. This was mainly done due to the growing number of new iPhones and iPads with different screen sizes, aspect ratios and resolutions.

Safe Area Layout Guides to the rescue!

The Safe Area Layout Guides provides you with a variety of additional layout anchors.
If you use storyboards, simply activate the Safe Area Layout Guides option and you’re done.
(Note: xib files have no layout guide to fall back to!).

Storyboard automatically handles compatibility for you, no need to check manually or provide a fallback.

Coding the interface programmatically is a bit more complicated because of the compatibility issues with iOS10 or earlier devices.
If you plan to only support devices from iOS11 or later, just use the safeAreaGuide property of UIViewController and anchor your constraints to them. No need to write exceptions at all.

If you plan to only support iOS10 or earlier you have to explicitly write a check like this one:

...

if #available(iOS 11.0, *) {  
    child.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true

} else {
        child.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
}

...

These checks can get quite unmaintainable when using a lot of layout constraints. And there's always the danger that you forget to also update the fallback constraints.

A small extension does the job

A simple solution is to use a UI Framework to handle that task for us. But I personally tend to limit the amount of third-party frameworks to the minimum. Especially when I only need this tiny part of a huge framework.

For me, this small extension does the job:

import UIKit

extension UIView {

    var safeTopAnchor: NSLayoutYAxisAnchor {
        if #available(iOS 11.0, *) {
            return safeAreaLayoutGuide.topAnchor
        }
        return topAnchor
    }

    var safeBottomAnchor: NSLayoutYAxisAnchor {
        if #available(iOS 11.0, *) {
            return safeAreaLayoutGuide.bottomAnchor
        }
        return bottomAnchor
    }

    var safeLeadingAnchor: NSLayoutXAxisAnchor {
        if #available(iOS 11.0, *) {
            return safeAreaLayoutGuide.leadingAnchor
        }
        return leadingAnchor
    }

    var safeTrailingAnchor: NSLayoutXAxisAnchor {
        if #available(iOS 11.0, *) {
            return safeAreaLayoutGuide.trailingAnchor
        }
        return trailingAnchor
    }

    var safeCenterXAnchor: NSLayoutXAxisAnchor {
        if #available(iOS 11.0, *) {
            return safeAreaLayoutGuide.centerXAnchor
        }
        return centerXAnchor
    }

    var safeCenterYAnchor: NSLayoutYAxisAnchor {
        if #available(iOS 11.0, *) {
            return safeAreaLayoutGuide.centerYAnchor
        }
        return centerYAnchor
    }

    var safeWidthAnchor: NSLayoutDimension {
        if #available(iOS 11.0, *) {
            return safeAreaLayoutGuide.widthAnchor
        }
        return widthAnchor
    }

    var safeHeightAnchor: NSLayoutDimension {
        if #available(iOS 11.0, *) {
            return safeAreaLayoutGuide.heightAnchor
        }
        return heightAnchor
    }
}

This extension anchors decide wether I can you the new Safe Area Layout Guide anchors or the legacy ones. Just use the layout anchors of the extension and you’re done:

child.topAnchor.constraint(equalTo: view.safeTopAnchor).isActive = true

fin