关于iPhone X 的适配

1.屏幕尺寸相关变化

  1. 高度增长了145pt,变成812pt.
  2. 屏幕圆角显示,注意至少留10pt边距。
  3. 状态栏高度由20pt变成44pt,留意这个距离就能避开“刘海”的尴尬,相应的导航栏以上变化64->88。
  4. 底部工具栏须要为home indicator留出34pt边距。
  5. 物理分辨率为1125px * 2436px.

2.横竖屏安全区对比

3.其余设备安全区域对比

4.应用设计

5.控件布局

更多可查看官方文档和视频Creating apps for iPhone X.json

如何让APP适配?

APP启动样式适配

相信有一部分道友的APP在iPhone X上运行时并无像想象中那样占满整个屏幕, 而是保持着原有的高度 在屏幕中心位置, 针对这个问题 目前通过实验得出能够经过如下方式使APP按照全屏模式运行:安全

  1. 经过LaunchScreen.storyboard方式启动
  2. 若是使用的是Assets中的LaunchImage, 在增长了iPhone X尺寸的图片配置后.

LaunchScreen.storyboard方式不用多说, 这里说一下如何在LaunchImage中增长iPhone X尺寸的图片配置.app

准备一张尺寸:1125 * 2436的启动图片, 移动到LaunchImage的Finder目录中, 并在LaunchImage中的Contents.json文件中增长 (注意Json格式):iphone

{
    "extent" : "full-screen",
    "idiom" : "iphone",
    "subtype" : "2436h",
    "filename" : "图片名.png",
    "minimum-system-version" : "11.0",
    "orientation" : "portrait",
    "scale" : "3x"
}

按照以上方式配置就彻底解决了这个问题.ide

APP内部样式适配

iOS11为UIViewControllerUIView增长了两个新的属性safeAreaInsetssafeAreaLayoutGuide, 经过这两个属性咱们能够得到安全区域的范围, 经过上图能够很清楚的看到安全区域的范围, 咱们要作的是让那些不能被遮挡的内容和控件在安全区域范围内显示, 注意!这句话很是重要.工具

  • safeAreaInsets 适用于手动计算.
  • safeAreaLayoutGuide 适用于自动布局.

Frame布局方式适配示例

通常来讲 能够经过在原有视图坐标计算时加入安全区域的范围值, 下面举个例子:布局

一个APP 它的NavigationBar使用的是自定义的UIView, 并不是UINavigationBar, 这个自定义的UIViewframe属性为CGRectMake(0, 0, 375, 64).
这样的UIView在其余设备上是没有问题的, 标准的导航栏尺寸, 可是若是运行在iPhone X上 你会发现看上去无比的别扭, 由于异形屏幕会形成部分显示内容的遮挡问题, 这时候就要用到安全区域这个概念来解决这一问题.ui

先说一说一般自定义导航栏的结构, 高度是为64 由44高度的导航栏内容区域和20高度的状态栏区域(电池条那部分 status bar)组成, 44高度的导航栏内容区域用来显示导航栏上的控件, 如返回按钮 标题视图等等, 如今, 在iPhone X上, 原来的状态栏(status bar)高度再也不考虑了, 取而代之的是安全区域顶部间距safeAreaInsets.top, 咱们将原有的结构改成 安全区域顶部距离屏幕的距离safeAreaInsets.top + 导航栏内容区域44, 这样完成了一个自定义导航栏视图在iPhone X上的适配.设计

下面是适配先后的效果对比:3d

再来看一下适配后的自定义导航栏视图的UI结构

这只是举一个简单的例子, 由于不一样的应用设计都是不一样的, 可是适配的思路都是同样的, 仍是那句话 咱们要作的是让那些不能被遮挡的内容和控件在安全区域范围内显示, 在计算布局时 将安全区域这个新特性考虑进去, iPhone X的适配也不是难事.

说一下在代码中的安全区域的适配该如何去写:

iOS11 为UIViewControllerUIView增长了一个新的方法 - (void)viewSafeAreaInsetsDidChange;

这个方法如名字同样 在安全区域改变后会被调用, 咱们能够在须要适配的UIViewControllerUIView中重写这个方法, 而且在这个方法中来根据safeAreaInsets属性更新子视图控件的布局位置.

这里有一点要注意的是当UIViewController调用- (void)viewDidLoad时它的全部子视图的safeAreaInsets属性都等于UIEdgeInsetsZero, 也就是说在- (void)viewSafeAreaInsetsDidChange;方法调用前 是没法经过当前视图控制器的子视图获取到safeAreaInsets的, 不过获取当前window对象的safeAreaInsets属性用来计算也是能够的, 可是不建议这么作, 一个视图控制器的子视图的处理固然要以它所在的控制器为准.

- (void)viewSafeAreaInsetsDidChangeUIViewController中第一次调用的时间是在- (void)viewWillAppear:(BOOL)animated调用以后, 在- (void)viewWillLayoutSubviews调用以前.

固然若是你要改变一个UIViewControllersafeAreaInsets值, 能够经过设置addtionalSafeAreaInsets属性来实现, 例如你要自定义一些特殊的样式时.

若是你改变了一个UIViewControllersafeAreaInsets属性值, - (void)viewSafeAreaInsetsDidChange也会被调用.

另外, 给道友们的分享一个获取某View安全区域范围的宏

#define VIEWSAFEAREAINSETS(view) ({UIEdgeInsets i; if(@available(iOS 11.0, *)) {i = view.safeAreaInsets;} else {i = UIEdgeInsetsZero;} i;})

使用起来比较简洁

VIEWSAFEAREAINSETS(view).left

VIEWSAFEAREAINSETS(self.view).right

AutoLayout布局方式示例

iOS11之前,咱们布局时, 视图的 top 和 bottom 通常参照的是 Top Layout Guide 和 Bottom Layout Guide.

iOS11之后, 那两个参照已经 deprecated (过期)了, 而是被Safe Area所取代.

参考自官方文档

相关文章
相关标签/搜索