iPhoneX(刘海屏)适配

iPhoneX(刘海屏)适配

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

区别

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

普通屏幕iPhoneX(刘海屏)系列
状态栏高度2044
导航栏高度6488
tabBar4983(其中有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作为自定义导航栏。

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

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

适配效果图

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

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

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

iOS 11 safe area layout guide backwards compatibility --stackOverflow

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值