欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

iPhoneX(刘海屏)适配

程序员文章站 2024-03-25 10:02:10
...

iPhoneX(刘海屏)适配

在 iOS11的时候,苹果破天荒发布了一款新屏幕样式的手机,俗称刘海屏。世人皆道丑,而后纷纷买之。自此,iOS 开发者们也走向了 iPhoneX系列的适配之旅。

区别

状态栏导航栏的改变和底部 Home Indicator的新增 。

普通屏幕 iPhoneX(刘海屏)系列
状态栏高度 20 44
导航栏高度 64 88
tabBar 49 83(其中有34Home Indicator交互区)

导航栏实际内容展示高度还是44,只是状态栏变高。

使用系统原生的导航栏、tabbar系统会自动适配。自定义的都需要手动适配X。比如隐藏了导航栏,使用自定义View代替导航栏的时候,你就需要手动适配(打码判断或者参考 SafeArea添加约束)。

iOS 11也引入了安全区域 SafeArea 的概念,以便我们适配和布局参考。

底层View添加约束的时候减少以superView为参考,使用Safe area为约束布局依据,这样就不用关注是否为刘海屏。

除了这些,还有键盘高度的增加等。

判断 iPhoneX 系列

有部分小伙伴是通过获取屏幕宽高各版本设备尺寸来判断,但是这样的弊端是,每增加一次设备都有可能需要添加,非常不推荐。而是应该用 keyWindow 的 SafeArea.bottom来判断。

Swift

extension UIDevice {
    /// 是否为 IphoneX (刘海屏)系列
    static var isIphoneXSeries: Bool {
        var keyWindow = UIApplication.shared.keyWindow
        if #available(iOS 13, *), keyWindow == nil {
            keyWindow = UIApplication.shared.windows.first
        }
        if #available(iOS 11.0, *), UIDevice().userInterfaceIdiom == .phone {
            if let key = keyWindow, key.safeAreaInsets.bottom > 0 { // 不能判断 top(普通屏幕为20, 刘海屏为44),而且还要考虑屏幕旋转问题。
                return true
            }
        }
        return false
    }
}

Objective-C宏定义

#define kIS_iPhoneX_Series ({BOOL isPhoneX = NO;\
if (@available(iOS 13.0, *)) {\
    isPhoneX =  [UIApplication sharedApplication].windows.firstObject.safeAreaInsets.bottom > 0.0;\
    }\
else if (@available(iOS 11.0, *)) {\
    isPhoneX = [[UIApplication sharedApplication] delegate].window.safeAreaInsets.bottom > 0.0;\
}\
(isPhoneX);}) 

其他Objective-C相关宏定义

#define kNavBar_Content_Height 44.0f  
#define kStatusBar_Height (kIS_iPhoneX_Series==YES)?44.0f: 20.0f
#define kNavBar_Height (kIS_iPhoneX_Series==YES)?88.0f: 64.0f
#define kTabBar_Height (kIS_iPhoneX_Series==YES)?83.0f: 49.0f

Home Indicator 的影藏

针对某些界面,也许我们希望全界面显示,影藏Inducator

这时候需要重写ViewController中的如下方法:

// 重写 控制home indicator的影藏
// 没有交互两秒后影藏
-(BOOL)prefersHomeIndicatorAutoHidden{
    return YES;
}

Xib适配iPhoneX(兼容 iOS11 之前版本)

iOS11版本以上

如果是基于iOS11适配X,你只需要将约束基准参考Safe Area,就可以解决大部分导航栏和底部栏的适配。

iOS11版本以前

你就需要以SuperView为基准的辅助约束,否则还是会导致被状态栏挡住的问题。

综合解决:

  1. 添加两条约束

  2. Safe Area为基准的约束 优先级 小于 以Super View的。

  3. 将SuperView为基准的约束关系设置为大于等于【如下图】。

添加一个UIView作为自定义导航栏。

iPhoneX(刘海屏)适配[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vWmNTRY4-1604631069553)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

同样的方法也可以适配底部导航栏或视图。

适配效果图

iPhoneX(刘海屏)适配[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PI6xaoQz-1604631069554)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

Storyboard里面只需要添加以SafeArea为基础的约束即可。

参考:Safe area layout guides in xib files - iOS 10 --*

iOS 11 safe area layout guide backwards compatibility --*

扩展:准确获取iPhone设备型号

详细推荐参考:适配iOS11与iPhoneX