Supporting iPhone X

When Apple revealed the iPhone X with a top “notch” and bottom home screen indicator the reason behind some SDK changes at WWDC 2017 became clearer. Safe area layout guides may help but there are still some gotchas for table/collection views and the search bar.

Safe Area Layout Guide

Apple added the safe area layout guide in iOS 11 replacing the top and bottom layout guides with a single guide. Here is what the safe area looks like on an iPhone 8 in portrait with just a top status and navigation bar:

iPhone 8 portrait

The safe area allows for a status bar (20 points) and navigation bar (44 points) at the top and a tab bar or tool bar at the bottom. Here is what happens to the safe area when we rotate the device to landscape:

iPhone 8 landscape

The system hides the status bar in landscape and the navigation bar has a smaller height of 32 points. Notice how the left and right insets are always zero. Now compare how this works with the iPhone X. First in portrait:

iPhone X portrait

The iPhone X has a taller aspect ratio. The status bar has grown to allow for the center housing (“the notch”) and rounded corners. This increases the top inset to 88 points.

Apple replaced the physical home button with a swipe up gesture and overlays a home control indicator at the bottom of the screen. This means our safe area now has a 34 point inset at the bottom (more if we add a tab bar or tool bar).

The biggest change happens when we rotate to landscape. It does not matter if the notch is on the left or right. Each side now has a 44 point inset:

iPhone X landscape

If you support landscape on the iPhone make sure you test on the iPhone X.

Supporting The iPhone X

If you are lucky linking against the iOS 11 SDK may be all you have to do. Your chances of being lucky grow if you stick to standard UIKit controls and you already adopted safe area layout guides after WWDC 2017 (and use a launch storyboard). The reality is likely to be different. Here is a list of problem areas I have seen so far:

Controls too close to screen edges

If you are not using safe area layout guides or layout margins there is a good chance your controls will end up too close to the device edges. The rounded edges, top central housing or bottom home indicator can clip, hide or overlay controls that would be fine on other iPhone models.

For example a button positioned 8 points in from the bottom and left edges of the superview. The rounded corners clip the button and the home control indicator covers it.

Clipped button

Move controls away from the edges on the iPhone X. Use the safe area layout guide and layout margins guide when creating constraints (use safeAreaIsets or layoutMargins if setting frames manually):

let margin = view.layoutMarginsGuide
NSLayoutConstraint.activate([
  button.leadingAnchor.constraint(equalTo: margin.leadingAnchor),
  button.bottomAnchor.constraint(equalTo: margin.bottomAnchor)
])

Safe button

Note: By default the system adjusts the layout margin guide to always fall within the safe area.

Swipe Up Gestures

If you rely on a swipe up gesture from the bottom screen edge you are going to make life hard for your users. On the iPhone X this gesture replaces the physical home button. You can give your gesture priority (see avoiding conflicts with system gestures) but this is probably not a good idea given the importance of this gesture on the iPhone X.

Unfortunately this looks like one area where you will need to rethink your app design. Avoid swipe up gestures from the bottom edge that conflict with the home gesture.

If you use a search bar with a table view you will most likely have code that looks something like this to add the search bar to the table view header:

let searchController = UISearchController(searchResultsController: searchResultsViewController)
searchController.searchResultsUpdater = self
tableView.tableHeaderView = searchController.searchBar

On an iPhone X in portrait this is not too bad:

Search Bar Portrait

There is a more serious problem in landscape. The rounded corners clip the search bar and the cancel button.

Clipped Search Bar

Apple integrated the search controller into the navigation bar in iOS 11. Instead of adding the search bar to the table view header add the search controller to the navigation item. The navigation bar then takes care of keeping the search bar and button inside the rounded corners. You can fall back to the table view header for iOS 10 and earlier:

if #available(iOS 11, *) {
    navigationItem.searchController = searchController
    navigationItem.hidesSearchBarWhenScrolling = false
} else {
    tableView.tableHeaderView = searchController.searchBar
}

This is what it now looks like on an iPhone X:

Safe Search Bar

Table View Content Insets

There is a new property (insetsContentViewsToSafeArea) on table views in iOS 11 that controls whether the content view of a table view cell is inset for the safe area. This is true by default which causes a subtle change with table views in landscape on an iPhone X.

The table view cell background view extends fully to the edges but the content view is inset to stay within the safe area. On the iPhone 8 this changes nothing as the left and right safe area insets are zero. For example if I set a background color on the content view of a table view cell it goes edge to edge:

iPhone 8 content view color

On the iPhone X this no longer works as expected:

iPhone X content view color

If you want the background color for your cell to extend to the screen edges on an iPhone X make sure you set it on the backgroundView of the cell and not the contentView:

iPhone X background view color

Further Reading

The two Fall 2017 Apple developer videos covering the iPhone X are short and to the point: