适配iPhone X -- 短视频SDK中的实践

适配iPhone X -- 短视频SDK中的实践_第1张图片
iPhone X

前言

最近苹果发布iPhone X,随后小伙伴的 X 都到货了,适配问题也接踵而至。

本篇主要内容分为:

  • iPhone X尺寸参数
  • UI适配
  • 极端情况处理
  • 实践案例
  • 总结

1.iPhone X尺寸参数

1.1 首先来围观一下模拟器的 iPhone X的外观

适配iPhone X -- 短视频SDK中的实践_第2张图片
图1. safearea示意

下面这点先记住这很重要,格式UIEdgeInsetsMake(上, 左,下,右)。

  1. iPhone X竖屏时:占满整个屏幕的控制器的view的safeAreaInsets是(44,0,34,0) ;
  2. iPhone X横屏时:是(0,44,21,44),inset后的区域正好是safeAreaLayoutGuide区域。

safeAreaInsets是相对于屏幕的物理边界计算的偏移量,通俗一点就是:

  1. 竖屏: 距离顶部(物理屏幕顶边)偏移44,距离左侧偏移0,距离底部偏移34,距离右边偏移0(从右向左偏移别搞错了);
  2. 横屏: 距离顶部(物理屏幕顶边)偏移0,距离左侧偏移44,距离底部偏移21(注意横屏底部有home 虚拟键),距离右边偏移44(同样注意不是竖屏的30了)。

进过测试发现,Margins 区域有10个像素点就是上边 的 40 - 30 = 10的作用区间(我的理解应该是为了压力触摸屏的事件响应范围),还有特别留意一下横屏的时候,顶部和底部的区别,顶部为0,底部要保留21的 pts(points)来显示 home 虚拟键,记得获取屏幕宽度或者高度的时候要做好减去 21 的准备。

穿黑色外套 不穿外套
适配iPhone X -- 短视频SDK中的实践_第3张图片
图2. 略显优雅
适配iPhone X -- 短视频SDK中的实践_第4张图片
图3. 略显尴尬

1.2 实际场景

适配iPhone X -- 短视频SDK中的实践_第5张图片
图4. 实际测试中的刘海样式

苹果扁平化凹陷齐刘海设计,如图4所示。

1.3 工业化图纸尺寸

适配iPhone X -- 短视频SDK中的实践_第6张图片
图5. iPhone X顶部尺寸图纸
参数 size 尺寸 备注
屏幕宽高 375 x 812 pt(point)
屏幕宽高比 9:19.5 而不是普通的 9:16 了
整体屏幕高度 iPhone 6/7/8's高了145pt pt(point)
状态栏高度(status bar) 44 比原来高出了24pt(并且空余的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 键范围

注意事项:

  1. 注意: 别搞错了status bar和FaceID传感器区域范围,因为状态栏(status bar)和传感器区域(sensor housing)之间还是有点间隙的间隙是 6 pt;
  2. status bar空余的24(44-20)pts 不能被 app 使用,因为他是给Face ID相关传感器留出区域.而且我们不能改变出现比如定位的图标、通话、和其他后台任务的图标的小大;
  3. 这里说的pt(point)是开发人员的计算屏幕一倍的像素单位,不是视觉提供素材的pixel像素;

2. UI适配

看完各种尺寸,我们来说一下 UI 适配工作。

2.1 工作分工

  • UI(视觉设计师)的素材提供;
  • RD(研发工程师)的UI相关适配;

2.2 适配范围

设计和开发同学需要考虑适配的范围,如图:

适配iPhone X -- 短视频SDK中的实践_第7张图片
图6. 适配范围
  1. 传感器区域(sensor housing),就是那个顶部Face ID的遮盖区域(大家常说的刘海儿);
  2. 底部Home键标识的触发区域,就是那个底部的横条(home indicator);
  3. 圆角,四个定点的圆角问题。

三倍(3x)屏的图标素材问题

  1. 建议使用PDF格式或者矢量图;
  2. 使用@2x或者@3x图;
  3. 如果没有使用LaunchScreen.storyboard作为应用启动的话 3x图用不了。

2.3 研发的工作范围

  1. 适配 UI 的导航栏和状态栏
  2. 适配safeArea范围
适配iPhone X -- 短视频SDK中的实践_第8张图片
图7. 短视频录制顶部按钮适配前

如图7所示,防抖按钮、闪光灯都被刘海遮住了。

之前我们的作法是把导航栏隐藏掉然后填写上按钮,但是在 iPhone X上就不行了。因为会出现被刘海盖住,其实主要的原因是我们用的 Masonry 自动布局的 edge 超过了安全区范围。

适配iPhone X -- 短视频SDK中的实践_第9张图片
图8. 示例

遮住的问题比较通用,放置一个 View,并且让他的 edge 在 iOS11上 等于安全区范围。

那么我们为啥要这么搞呢?

  1. 我们需要适配 iPhone X 的 safeArea 并且兼容 iOS8;
  2. 后续处理事件:按钮、手势,都依赖这个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界面
适配iPhone X -- 短视频SDK中的实践_第10张图片
适配iPhone X -- 短视频SDK中的实践_第11张图片
适配iPhone X -- 短视频SDK中的实践_第12张图片
适配iPhone X -- 短视频SDK中的实践_第13张图片

3. 特殊case处理

3.1 手势

如果有些 app 使用的手势是从下往上滑动的话,会造成在 iPhone X上 滑动和 home 虚拟按键冲突的问题,那如果出现这种问题如何解决呢?

适配iPhone X -- 短视频SDK中的实践_第14张图片
图9. 手势从下往上滑动

我们需要需要开启 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,低版本怎么处理?

  1. 经过测试在iOS9之前用不了safeArea,必须iOS9 or later
  2. 如果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值:

  1. iPhone X 安全区 (0, 44, 375, 734).
  2. 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

你可能感兴趣的:(适配iPhone X -- 短视频SDK中的实践)