前言
最近苹果发布iPhone X,随后小伙伴的 X 都到货了,适配问题也接踵而至。
本篇主要内容分为:
- iPhone X尺寸参数
- UI适配
- 极端情况处理
- 实践案例
- 总结
1.iPhone X尺寸参数
1.1 首先来围观一下模拟器的 iPhone X的外观
下面这点先记住这很重要,格式UIEdgeInsetsMake(上, 左,下,右)。
- iPhone X竖屏时:占满整个屏幕的控制器的view的safeAreaInsets是(44,0,34,0) ;
- iPhone X横屏时:是(0,44,21,44),inset后的区域正好是safeAreaLayoutGuide区域。
safeAreaInsets是相对于屏幕的物理边界计算的偏移量,通俗一点就是:
- 竖屏: 距离顶部(物理屏幕顶边)偏移44,距离左侧偏移0,距离底部偏移34,距离右边偏移0(从右向左偏移别搞错了);
- 横屏: 距离顶部(物理屏幕顶边)偏移0,距离左侧偏移44,距离底部偏移21(注意横屏底部有home 虚拟键),距离右边偏移44(同样注意不是竖屏的30了)。
进过测试发现,Margins 区域有10个像素点就是上边 的 40 - 30 = 10的作用区间(我的理解应该是为了压力触摸屏的事件响应范围),还有特别留意一下横屏的时候,顶部和底部的区别,顶部为0,底部要保留21的 pts(points)来显示 home 虚拟键,记得获取屏幕宽度或者高度的时候要做好减去 21 的准备。
穿黑色外套 | 不穿外套 |
---|---|
1.2 实际场景
苹果扁平化凹陷齐刘海设计,如图4所示。
1.3 工业化图纸尺寸
参数 | size 尺寸 | 备注 |
---|---|---|
屏幕宽高 | 375 x 812 | pt(point) |
屏幕宽高比 | 9:19.5 | 而不是普通的 9:16 了 |
整体屏幕高度 | 比iPhone 6/7/8's 高了145 pt |
pt(point) |
状态栏高度(status bar) | 44 | 比原来高出了24 pt(并且空余的24 (44-20)pts 不能被 app 使用,因为他是给Face ID 相关传感器留出区域) |
传感器区域(sensor housing) | 30 | 单位 pt,就是被挡住的那个 Face ID传感器区域 |
状态栏+导航栏高度(Navigation Bar) | 88 或 (带 title 样式的 140) | pt(point) |
底部 Toolbar | 83 | 不再是原来的 44 pt(point),如果横屏 Toolbar 高度 53 |
retina像素倍数 | 3x | 3倍屏 |
pixels像素 | 1125 x 2436 | 和 iPhone各种Plus版本一直 |
iPhone X 安全区 | frame 为(0, 44, 375, 734) | 对比iPhone6/6s安全区frame 为(0, 0, 375, 667) |
layout margins | 纵向 20,横向64 ) | 横向 margins 底部有那个 home 键范围 |
注意事项:
- 注意: 别搞错了status bar和FaceID传感器区域范围,因为状态栏(status bar)和传感器区域(sensor housing)之间还是有点间隙的间隙是 6 pt;
- status bar空余的
24
(44-20)pts 不能被 app 使用,因为他是给Face ID
相关传感器留出区域.而且我们不能改变出现比如定位的图标、通话、和其他后台任务的图标的小大; - 这里说的pt(point)是开发人员的计算屏幕一倍的像素单位,不是视觉提供素材的pixel像素;
2. UI适配
看完各种尺寸,我们来说一下 UI 适配工作。
2.1 工作分工
- UI(视觉设计师)的素材提供;
- RD(研发工程师)的UI相关适配;
2.2 适配范围
设计和开发同学需要考虑适配的范围,如图:
- 传感器区域(sensor housing),就是那个顶部
Face ID
的遮盖区域(大家常说的刘海儿); - 底部
Home键
标识的触发区域,就是那个底部的横条(home indicator); - 圆角,四个定点的圆角问题。
三倍(3x)屏的图标素材问题
- 建议使用
PDF
格式或者矢量图; - 使用
@2x
或者@3x
图; - 如果没有使用
LaunchScreen.storyboard
作为应用启动的话3x
图用不了。
2.3 研发的工作范围
- 适配 UI 的导航栏和状态栏
- 适配safeArea范围
如图7所示,防抖按钮、闪光灯都被刘海遮住了。
之前我们的作法是把导航栏隐藏掉然后填写上按钮,但是在 iPhone X上就不行了。因为会出现被刘海盖住,其实主要的原因是我们用的 Masonry 自动布局的 edge 超过了安全区范围。
遮住的问题比较通用,放置一个 View,并且让他的 edge 在 iOS11上 等于安全区范围。
那么我们为啥要这么搞呢?
- 我们需要适配 iPhone X 的 safeArea 并且兼容 iOS8;
- 后续处理事件:按钮、手势,都依赖这个view。
代码实现如下:
if (@available(iOS 11.0, *)) {
[self.canRotateView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
make.left.equalTo(self.view.mas_safeAreaLayoutGuideLeft);
make.right.equalTo(self.view.mas_safeAreaLayoutGuideRight);
}];
} else {
[self.safeAreaView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
}
下面是完成之后的效果图:
Launch界面 | config界面 | record界面 | edit界面 |
---|---|---|---|
3. 特殊case处理
3.1 手势
如果有些 app 使用的手势是从下往上滑动的话,会造成在 iPhone X上 滑动和 home 虚拟按键冲突的问题,那如果出现这种问题如何解决呢?
我们需要需要开启 edge protect:The screen edges for which you want your gestures to take precedence over the system gestures
。
在 UIViewController 里面返回要触摸返回键的范围:
func preferredScreenEdgesDeferringSystemGestures() -> UIRectEdge
objc 版本
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures{
return UIRectEdgeAll;
}
这样的话,用户滑动一次手势响应上滑事件。如果滑动两次才会触发home indicator
。
3.2 隐藏底部 home 条
某些APP是希望隐藏掉底部的home横条的,如何实现?
其实这是一种被动的视图响应体验,AutoHidden:Returns a Boolean indicating whether the system is allowed to hide the visual indicator for returning to the Home screen.
。
更改prefersHomeIndicatorAutoHidden
设置,这样如果用户没有触发底部的home 条
(home indicator)几秒,home 条
(home indicator)会淡出隐藏。
func prefersHomeIndicatorAutoHidden() -> Bool
Objective-C 版本
- (BOOL)prefersHomeIndicatorAutoHidden{
return YES;
}
4. iPhone X实践
4.1 safeArea 低版本兼容
在 iOS11上开启safeArea,低版本怎么处理?
- 经过测试在
iOS9
之前用不了safeArea
,必须iOS9 or later
; - 如果APP需要兼容 iOS 8.0的话,建议去掉
safeArea
,否则编译报错。
解决的方式:参考我们的短视频适配,使用一个背景 View来做支撑,并且使它的 edge 边缘处于safeArea
范围内。
if ( NS_AVAILABEL(iOS 11.0)) {
// iOS11 支持安全区域范围
} else {
// iOS11之前不支持安全区范围
}
4.2 Masonry edge 不能等于 safeAreaGuide?
当前项目基本都是 xib 拖拽控件,使用 masonry 自动布局。
如果一个 view的上、左、下、右 4个边缘等于父视图的话我们经常写下面代码:
[self.xxxView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
为支持 safeArea,Masonry
库提供了safeAreaGuide
[self.safeAreaView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view.mas_safeAreaLayoutGuide);
}];
但是经过验证,这样写会触发Masonry
库 bug 导致 crash。
看下边的例子:
// 底部segement
[self.panelTabbar mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.bottom.equalTo(self.view);
make.height.equalTo(@44);
}];
改成 iOS11,这个写法就会不支持:
// 底部segement
[self.panelTabbar mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.bottom.equalTo(self.view.mas_safeAreaLayoutGuide);
make.height.equalTo(@44);
}];
需要改动为:
// 底部segement
[self.panelTabbar mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.mas_safeAreaLayoutGuideLeft);
make.right.equalTo(self.view.mas_safeAreaLayoutGuideRight);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
make.height.equalTo(@44);
}];
说明
这个已经给 Masonry 库提了 issue 近期应该会修复。
4.3 safeArea 的坐标(frame)
如果有一种需求需要计算 iPhone 的safeArea宽高等于多少?
如下代码可以得到正确的范围:
// 计算范围
if (@available(iOS 11.0, *)) {
NSString * safeAreaRect = NSStringFromCGRect(self.view.safeAreaLayoutGuide.layoutFrame);
NSLog(@"安全区范围:%@",safeAreaRect);
}
在 ViewController 里面测试,safeArea frame值:
- iPhone X 安全区 (0, 44, 375, 734).
- iPhone 6s 安全区 (0, 0, 375, 667).
可以看到,iPhone X比iPhone 6s高了:734 - 667 = 67。
在视频录制时,会导致视频比例不对。
解决办法:
推荐安全区顶部到底部,宽高比值等于标准的 3:4 或者 9:16。
4.4 适配 iPhone X常用的宏
- UIScrollView
iOS 11
不再推荐使用scrollView的automaticallyAdjustsScrollViewInsets
属性,使用contentInsetAdjustmentBehavior
属性来替代。下面的宏可以更方便地设置adjustScrollViewInsetNever。
#define AdjustsScrollViewInsetNever(controller,view) if(@available(iOS 11.0, *)) {view.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;} else if([controller isKindOfClass:[UIViewController class]]) {controller.automaticallyAdjustsScrollViewInsets = false;}
- 高度系数宏
高度系数 812.0 是iPhone X的高度尺寸,667.0表示是iPhone 8 的高度。
#define kHeightCoefficient (kScreenHeight == 812.0 ? 667.0/667.0 : kScreenHeight/667.0)
5. 总结
以上是金山云短视频SDK适配iPhone X一些实践,因为SDK主要是用于短视频录制和编辑,并不能覆盖iPhone X适配的所有问题,如有遗漏欢迎补充。
转载请注明:
作者金山视频云,首发简书 Jianshu.com
欢迎大家试用金山云短视频SDK,github仓库地址:
https://github.com/ksvc/KSYMediaEditorKit_iOS
金山云SDK相关的QQ交流群:
- 视频云技术交流群:574179720
- 视频云iOS技术交流:621137661