Identify iPhones with Notch Programmatically Identify iPhones with Notch Programmatically xcode xcode

Identify iPhones with Notch Programmatically


I had to dig around quite a bit but found the answer (I'd like to shout out to user6788419 whose right answer was berried deep in another thread).

First of all, the above code is correct. Checking if the safe area's bottom inset is larger than zero will accurately identify iPhones with a notch (as of this writing). So, this is correct:

if (@available( iOS 11.0, * )) {    if ([[[UIApplication sharedApplication] keyWindow] safeAreaInsets].bottom > 0) {        // iPhone with notch    }}

However, it matters where you put the above statement in your code because UIWindow is not available until the first run loop has concluded. That means, if you check the notch in your viewDidLoad or before it concluded (in your init for example), the bottom inset will always be zero.

If you, similarly to me, need this check to setup your main view, you can just move all your setup into separate function (such as postViewDidLoad) and call it once viewDidLoad has concluded:

[self performSelector:@selector(postViewDidLoad) withObject:nil afterDelay:0.0f];

Or, alternatively, you enclose it:

dispatch_async(dispatch_get_main_queue(), ^{    // Check notch here});


Swift 5 and (iOS12 or Above)

var isNotch: Bool {   return (UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0) > 0}


Updated for Swift 5 and iOS14

This solves the keyWindow deprecation warning.

var hasNotch: Bool {        let bottom = UIApplication.shared.windows.first{ $0.isKeyWindow }?.safeAreaInsets.bottom ?? 0 return bottom > 0               }