Extra bottom space/padding on iPhone X?

IosIphoneSwiftIphone X

Ios Problem Overview


On the iPhone X in portrait mode, if you set a bottom constraint to safe area to 0, you will end up with an extra space at the bottom of the screen. How do you get programmatically the height of this extra padding ?

I managed to manually determine the height of this padding which is 34 and here is how I managed to implement it with iPhone X detection:

Swift 4.0 and Xcode 9.0

if UIDevice().userInterfaceIdiom == .phone
{
    switch UIScreen.main.nativeBounds.height
    {
        case 2436: //iPhone X
        self.keyboardInAppOffset.constant = -34.0
        default:
        self.keyboardInAppOffset.constant = 0
    }
}

Is there a cleaner way to detect the height of this padding ?

Ios Solutions


Solution 1 - Ios

In iOS 11, views have a safeAreaInsets property. If you get the bottom property of these insets you can get the height of the bottom padding while on iPhone X:

if #available(iOS 11.0, *) {
    let bottomPadding = view.safeAreaInsets.bottom
    // ...
}

(likewise for the top padding with status bar)

Solution 2 - Ios

In Objective-C

if (@available(iOS 11.0, *)) {
   UIWindow *window = UIApplication.sharedApplication.keyWindow;
   CGFloat bottomPadding = window.safeAreaInsets.bottom;
}

Solution 3 - Ios

var bottomPadding: CGFloat = 0.0
if #available(iOS 11.0, *) {
     let window = UIApplication.shared.keyWindow
     bottomPadding = window?.safeAreaInsets.bottom ?? 0.0
}

Now you can use bottomPadding as per your needs.

Solution 4 - Ios

If suddenly you have no view, for example, CollectionViewLayout, you can retrieve it from Window too:

private static var itemHeight: CGFloat {
    guard #available(iOS 11.0, *),
        let window = UIApplication.shared.keyWindow else {
            return Constants.itemHeight
    }
    return Constants.itemHeight - window.safeAreaInsets.bottom
}

Solution 5 - Ios

iOS 11 (a mix from answers above)

let padding = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0

Solution 6 - Ios

UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0.0

iOS 13 and up

Solution 7 - Ios

use this line to become your bottom value for iPhoneX

if #available(iOS 11.0, *) {
            let bottomPadding = view.safeAreaInsets.bottom
  }

and don't forget to add this in layoutSubviews() because safeAreaInsets has the correct size in layoutSubviews() otherwise you will become wrong values.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionstandoussetView Question on Stackoverflow
Solution 1 - IosPaoloView Answer on Stackoverflow
Solution 2 - Iosuser6788419View Answer on Stackoverflow
Solution 3 - IosHemangView Answer on Stackoverflow
Solution 4 - IosAzonView Answer on Stackoverflow
Solution 5 - IosMerricatView Answer on Stackoverflow
Solution 6 - Iosuser10447655View Answer on Stackoverflow
Solution 7 - IosOsmanView Answer on Stackoverflow