iOS 刘海屏适配

今年苹果发布了三款 iPhone,分别为 iPhone XS、iPhone XS Max 以及 iPhone XR,尽管大家都在吐槽刘海屏,但是苹果今年已经是 iPhone 系列标配刘海屏了。

虽然苹果为我们带来了更大屏幕尺寸的 iPhone XS Max 和 iPhone XR,尽管一个是6.5英寸一个是6.1英寸,并且 iPhone XS Max 的分辨率更是达到了 1242px × 2688px,但是对于我们开发者来说,这两者的物理尺寸都一个样,都是 414×896pt,而 6/7/8 Plus 系列的宽度也是 414pt,所以你可以把他们看作是 plus 系列的加长版。


/// 是否为异形屏(刘海屏)
BOOL isShapedScreen(void)
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        if (@available(iOS 11.0, *)) {
            static BOOL result = NO;
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                CGFloat width = MIN(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height);
                CGFloat height = MAX(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height);
                if (@available(iOS 12.0, *)) {
                    if (width == 414.0 && height == 896.0) {
                        result = YES; // iPhone XS Max / iPhone XR
                    }
                }
                if (width == 375.0 && height == 812.0) {
                    result = YES; // iPhone X / iPhone XS
                }
            });
            return result;
        }
    }
    return NO;
}

/// 是否为iPhone X / iPhone XS
BOOL iPhoneX(void)
{
    if (@available(iOS 11.0, *)) {
        static BOOL result = NO;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            if (isShapedScreen()) {
                CGFloat height = MAX(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height);
                if (height == 812.0) {
                    result = YES;
                }
            }
        });
        return result;
    }
    return NO;
}

/// 是否为iPhone XS Max
BOOL iPhoneXSMax(void)
{
    if (@available(iOS 12.0, *)) {
        static BOOL result = NO;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            if (isShapedScreen()) {
                CGFloat height = MAX(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height);
                if (height == 896.0 && UIScreen.mainScreen.scale == 3.0) {
                    result = YES;
                }
            }
        });
        return result;
    }
    return NO;
}

/// 是否为iPhone XR
BOOL iPhoneXR(void)
{
    if (@available(iOS 12.0, *)) {
        static BOOL result = NO;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            if (isShapedScreen()) {
                CGFloat height = MAX(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height);
                if (height == 896.0 && UIScreen.mainScreen.scale == 2.0) {
                    result = YES;
                }
            }
        });
        return result;
    }
    return NO;
}

附上 Swift 代码

/// 是否为异形屏(刘海屏)
let isShapedScreen : Bool = {
    if UI_USER_INTERFACE_IDIOM() == .phone {
        if #available(iOS 11.0, *) {
            let width = min(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
            let height = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
            if #available(iOS 12.0, *) {
                if width == 414.0 && height == 896.0 {
                    return true // iPhone XS Max / iPhone XR
                }
            }
            if (width == 375.0 && height == 812.0) {
                return true // iPhone X / iPhone XS
            }
        }
    }
    return false
}()

/// 是否为iPhone X / iPhone XS
let iPhoneX : Bool = {
    if #available(iOS 11.0, *) {
        if isShapedScreen {
            let height = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
            return (height == 812.0)
        }
    }
    return false
}()

/// 是否为iPhone XS Max
let iPhoneXSMax : Bool = {
    if #available(iOS 12.0, *) {
        if isShapedScreen {
            let height = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
            let scale = UIScreen.main.scale
            if height == 896.0 && scale == 3.0 {
                return true
            }
        }
    }
    return false
}()

/// 是否为iPhone XR
let iPhoneXR : Bool = {
    if #available(iOS 12.0, *) {
        if isShapedScreen {
            let height = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
            let scale = UIScreen.main.scale
            if height == 896.0 && scale == 2.0 {
                return true
            }
        }
    }
    return false
}()

设备 分辨率 图片资源
12.9” iPad Pro 2048px × 2732px @2x
10.5” iPad Pro 1668px × 2224px @2x
9.7” iPad 1536px × 2048px @2x
7.9” iPad mini 4 1536px × 2048px @2x
iPhone XS Max 1242px × 2688px @3x
iPhone XS 1125px × 2436px @3x
iPhone XR 828px × 1792px @2x
iPhone X 1125px × 2436px @3x
iPhone 8 Plus 1242px × 2208px @3x
iPhone 8 750px × 1334px @2x
iPhone 7 Plus 1242px × 2208px @3x
iPhone 7 750px × 1334px @2x
iPhone 6s Plus 1242px × 2208px @3x
iPhone 6s 750px × 1334px @2x
iPhone SE 640px × 1136px @2x

参考: