iPhoneX(刘海屏)适配
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为基准的辅助约束,否则还是会导致被状态栏挡住的问题。
综合解决:
-
添加两条约束
-
Safe Area为基准的约束 优先级 小于 以Super View的。
-
将SuperView为基准的约束关系设置为大于等于【如下图】。
添加一个UIView作为自定义导航栏。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vWmNTRY4-1604631069553)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
同样的方法也可以适配底部导航栏或视图。
适配效果图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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 --*
详细推荐参考:适配iOS11与iPhoneX