July 1, 2020

Hide home indicator with Swift

Hide home indicator with Swift

The iPhone X removed the home button and replaced it with what Apple calls the home indicator. Apple has allowed us to hide the home indicator which can be useful if your app needs to hide the indicator. Some examples could be for a video player app, photo app, map/navigation app or maybe even something like a game.

The code to hide the home indicator is quite simple, we need to override the prefersHomeIndicatorAutoHidden property.

Add the following to the view controller on which you want to hide the indicator:

override var prefersHomeIndicatorAutoHidden: Bool {
    return true
}
NOTE: The home indicator will hide after a few seconds, but as soon as the user touches the screen the home indicator will be shown.

According to Apple's documentation, which you can find here, if we change the return value of prefersHomeIndicatorAutoHidden, we should also call, setNeedsUpdateOfHomeIndicatorAutoHidden, this will only need to be called if you change prefersHomeIndicatorAutoHidden after the view loads.

In the below example I am just showing you how to call it, but you don't need to call it here. You need to call it wherever it makes sense within your app.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    setNeedsUpdateOfHomeIndicatorAutoHidden()
}

Caveat

While this code is quite simple, there is an issue. As I noted above, if the user touches the screen the home indicator will be shown again. Depending on the type of app, this could be a problem.

Using this behaviour might not work well with games because the user is interacting with the screen all the time and could, by accident, swipe up and background the app, the same goes with any interactive app.

How can we fix this? To fix this for interactive apps, we need to remove:

override var prefersHomeIndicatorAutoHidden: Bool {
    return true
}

And then we need to add the following:

override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge {
    return [.bottom]
}

This will not hide the home indicator, but it will grey it out. This will require a user to swipe up twice in order to background the app. If you change this value after the view has been loaded, you will need to call the following method:

setNeedsUpdateOfScreenEdgesDeferringSystemGestures()

Conclusion

The above examples are very simple code wise, but when I was testing this out I could not get it to work properly. From my testing you cannot use prefersHomeIndicatorAutoHidden and preferredScreenEdgesDeferringSystemGestures together. If you do, the prefersHomeIndicatorAutoHidden will take preference.

If you want to see the full source code, you can find it here.