Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone X Aligning object bottom to Safe Area ruins look on other devices

Tags:

Question on iPhone X Autolayout quirks.

I have two buttons, previously these would be aligned bottom to the superview with an offset of 20 to not have them touching the bottom of the screen (I've since changed the link to Safe Area not Superview).

Here's the original setup: iPhone 8 - Setup

Looks good as expected on older iPhones. iPhone 8 20 Offset

Now the 20 constant on the bottom constraint now makes the buttons look funky and too far up from the home bar on iPhone X. iPhone X 20 Offset

Logically, I need to remove the 20 constant from the constraint on iPhone X and have the buttons aligned directly with the bottom of the safe area. iPhone X - Setup

Looks good on iPhone X now. iPhone X 0 Offset

But now it's placing the buttons too close to the bottom of the screen on non home bar phones. iPhone 8 0 Offset

Any immediate solutions to this problem that I missed in the Apple docs? Can't use size classes since the iPhone X size class overlaps with the other iPhones in this case.

I could easily code to detect for iPhone X and set the constant on the constraint to 0 but I was hoping for a more elegant solution.

Thanks,

like image 815
0000101010 Avatar asked Oct 23 '17 00:10

0000101010


2 Answers

Another way to achieve this directly from the storyboard is to create two constraints:
1. Between your element and safe area with 250 priority with 0 constant
2. Between your element and the superview bottom with 750 priority and 20 constant and greater Than or Equal relation.

enter image description here

like image 171
Marcos Griselli Avatar answered Nov 03 '22 08:11

Marcos Griselli


The Apple Docs states there is a new declaration in iOS 11 which can be a solution to this problem. Currently iPhone X and iPhone 8 share the same size class so we must come up with another solution.

var additionalSafeAreaInsets: UIEdgeInsets { get set }

Add the following code below in your AppDelegate and all children of the rootViewController will inherit the additional safe area. Example screenshots below describe this behavior.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    if !self.isIphoneX() {
        self.window?.rootViewController?.additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)
    }

    return true
}

func isIphoneX() -> Bool {
    if #available(iOS 11.0, *) {
        if ((self.window?.safeAreaInsets.top)! > CGFloat(0.0)) {
            return true;
        }
    }
    return false
}

iPhone X Interface Builder Aligned to Safe Area

enter image description here

iPhone 8 Interface Builder Aligned to Safe Area

enter image description here

iPhone X Simulator - Master Screen

enter image description here

iPhone X Simulator - Details Screen

enter image description here

iPhone 8 Simulator - Master Screen

enter image description here

iPhone 8 Simulator - Details Screen

enter image description here

like image 38
3 revs Avatar answered Nov 03 '22 09:11

3 revs