更多可查看官方文档和视频Creating apps for iPhone X.json
相信有一部分道友的APP在iPhone X上运行时并无像想象中那样占满整个屏幕, 而是保持着原有的高度 在屏幕中心位置, 针对这个问题 目前通过实验得出能够经过如下方式使APP按照全屏模式运行:安全
LaunchScreen.storyboard
方式启动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
iOS11为UIViewController
和UIView
增长了两个新的属性safeAreaInsets
和safeAreaLayoutGuide
, 经过这两个属性咱们能够得到安全区域的范围, 经过上图能够很清楚的看到安全区域的范围, 咱们要作的是让那些不能被遮挡的内容和控件在安全区域范围内显示, 注意!这句话很是重要.工具
safeAreaInsets
适用于手动计算.safeAreaLayoutGuide
适用于自动布局.通常来讲 能够经过在原有视图坐标计算时加入安全区域的范围值, 下面举个例子:布局
一个APP 它的NavigationBar使用的是自定义的UIView
, 并不是UINavigationBar
, 这个自定义的UIView
的frame
属性为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 为UIViewController
和UIView
增长了一个新的方法 - (void)viewSafeAreaInsetsDidChange;
这个方法如名字同样 在安全区域改变后会被调用, 咱们能够在须要适配的UIViewController
和UIView
中重写这个方法, 而且在这个方法中来根据safeAreaInsets
属性更新子视图控件的布局位置.
这里有一点要注意的是当UIViewController
调用- (void)viewDidLoad
时它的全部子视图的safeAreaInsets
属性都等于UIEdgeInsetsZero
, 也就是说在- (void)viewSafeAreaInsetsDidChange;
方法调用前 是没法经过当前视图控制器的子视图获取到safeAreaInsets
的, 不过获取当前window对象的safeAreaInsets
属性用来计算也是能够的, 可是不建议这么作, 一个视图控制器的子视图的处理固然要以它所在的控制器为准.
- (void)viewSafeAreaInsetsDidChange
在UIViewController
中第一次调用的时间是在- (void)viewWillAppear:(BOOL)animated
调用以后, 在- (void)viewWillLayoutSubviews
调用以前.
固然若是你要改变一个UIViewController
的safeAreaInsets
值, 能够经过设置addtionalSafeAreaInsets
属性来实现, 例如你要自定义一些特殊的样式时.
若是你改变了一个UIViewController
的safeAreaInsets
属性值, - (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
iOS11之前,咱们布局时, 视图的 top
和 bottom
通常参照的是 Top Layout Guide
和 Bottom Layout Guide
.
iOS11之后, 那两个参照已经 deprecated
(过期)了, 而是被Safe Area
所取代.