Aspect Fit Layout Guide

Apple added a new layout guide in iOS 16 to help maximize the size of content with a certain aspect ratio within the safe area.

I don’t remember seeing this mentioned during WWDC. I learnt about it from this Twitter thread by Tyler Fox.

Safe Area Aspect Fit Layout Guide

The safeAreaAspectFitLayoutGuide is something of a curiosity. It’s a UILayoutGuide with the usual layout anchors but it also has an aspectRatio property:

var aspectRatio: CGFloat { get set }

It’s intended for “full-screen” content of a fixed aspect ratio like a media player. When you set the aspect ratio, the guide defines a safe area, centered in the window, that maximizes the content size for the aspect ratio so that the content is not clipped or covered by the curved corners, notch or dynamic island.

Window Guide

Unlike the standard safe area layout guide the aspect fit guide is not a property of UIView. Instead it only exists for the window:

extension UIWindow {
  @available(iOS 16.0, *)
  open var safeAreaAspectFitLayoutGuide: UILayoutGuide &
    UILayoutGuideAspectFitting { get }
}

It also comes with a warning:

The safeAreaAspectFitLayoutGuide should only be used with views that are direct subviews of, or very close descendants of, the guide’s window.

It’s not intended that you use it with views buried deep in a view controller:

Creating constraints from this layout guide to views deeper in the view heirarchy or across views owned by child view controllers can significantly degrade performance and possibly raise an exception.

How Do I Use It?

Using the guide is a two step process:

  1. Set the aspect ratio.
  2. Create constraints from the content view to the layout guide.

The aspect ratio must be greater than 0 and less than or equal to 100. The default value is 1.0. To try it out I created a view with a fixed aspect ratio of 21:9 representing some ultra widescreen video content:

class AspectView: UIView {
  // 21:9 - ultra widescreen
  let aspectRatio: CGFloat = 21/9
  ...
  private func setupView() {
    NSLayoutConstraint.activate([
      widthAnchor.constraint(equalTo: heightAnchor,
      multiplier: aspectRatio)
    ])
  }
}

I’m adding this view directly to the window in the scene delegate:

func scene(_ scene: UIScene,
  willConnectTo session: UISceneSession,
  options connectionOptions: UIScene.ConnectionOptions) {
  guard let window = window else { return }

  let aspectView = AspectView()
  window.addSubview(aspectView)

Next I set the aspect ratio of the layout guide to match the aspect ratio of my content:

let guide = window.safeAreaAspectFitLayoutGuide
guide.aspectRatio = aspectView.aspectRatio

Finally, I constrain my content view to the guide. That’s a little bit of work as I want my content to fill, but never overflow, the guide area:

let widthConstraint = aspectView.widthAnchor.constraint(equalTo: guide.widthAnchor)
widthConstraint.priority = .defaultLow

NSLayoutConstraint.activate([
  aspectView.centerXAnchor.constraint(equalTo: guide.centerXAnchor),
  aspectView.centerYAnchor.constraint(equalTo: guide.centerYAnchor),
  aspectView.widthAnchor.constraint(lessThanOrEqualTo: guide.widthAnchor, multiplier: 1.0),
  aspectView.heightAnchor.constraint(lessThanOrEqualTo: guide.heightAnchor, multiplier: 1.0),
  widthConstraint
])

The first two constraints center the content view in the guide area. The two inequality constraints make sure it never exceeds the guides width or height. The final optional width constraint makes the content as wide as possible without breaking the other constraints.

Note: This is more complicated than is likely necessary in practise so I can experiment with different aspect ratios. It can be simplified if I know my width is always greater than the height.

Here’s how it looks on an iPhone 14 Pro in landscape:

iPhone 14 Pro simulator in landscape

The content view is shown in yellow, the black rectangle is an area of the same 21:9 aspect ratio that is centered on, and fitted inside, the standard safe area layout guide. Here are the dimensions of the two areas for comparison:

  • Aspect fit: 756 x 323
  • Safe area: 734 x 314.67

Using the aspect fit guide gives us a bigger area but also centers the content in the device window. The standard safe area layout guide has a 21 point inset at the bottom of the device to allow for the home screen indicator. This both reduces the available space and pushes the content area up towards the top of the device.

The difference is more obvious if I give my content a 1:1 (square) aspect ratio:

iPhone 14 Pro simulator in landscape

I’ve also left the home screen indicator visible in this screenshot. Note how the yellow content constrained to the safe area aspect fit layout guide extends to the top and bottom edges of the device.

Note: To request the system hides the home screen indicator override the prefersHomeIndicatorAutoHidden property in your view controllers:

override var prefersHomeIndicatorAutoHidden: Bool {
  return true
}

How Deep Can You Go?

The documentation for the guide warns you to only use it with subviews that are “very close descendants” of the window. I’ve used it with a subview of a view controllers root view without seeing a problem so I suppose that is close enough.

Note: Remember that the root view of a view controller is not immediately part of the window hierarchy. If you check the window property of the view controller’s view in viewDidLoad it will still be nil. That means you can’t add any constraints with the window guide until much later in the view lifecycle.

Summary

The safe area aspect fit layout guide has a very specific use-case for fixed aspect ratio content like media players. If that’s your situation, using it gives you the largest safe area for your content. Most of the time you should just use the standard safe area layout guide.

The Apple documentation spells it out:

This layout guide should only be used for fixed aspect ratio content that is indended to fill the window (such as image or video content) and is not a replacement for the standard safeAreaLayoutGuide on each UIView which should be used for most content layout.

If you want to learn more about using layout guides you should take a look at my book Modern Auto Layout