YownYang's blog

如何适配iPhoneX

如何适配iPhone X

基本信息

  • 它是一个3倍屏,也就是3x,通俗讲就是1个pt3个px
  • 竖屏状态下,宽度是375pt,高度是812pt,分辨率是1125px × 2436px;横屏状态下,宽高相反
  • 系统的UIKit会自动适配,例如UINavigationBar,UITabbar,UITableView
  • 如果你使用Auto Layout,特别是使用margin layout guides和safe area的话,布局会非常简单(这两个概念后面细说)

margin layout guides 和 safe area

首先说明下margin layout guides,它是在iPhone X出来之前每一个控制器都有的两个属性,分别叫做topLayoutGuidebottomLayoutGuide。这两者合起来组成了一个可以用于布局的标准高度,也就是你正常情况能用来放置控件的区域,因为竖屏状态左右是不会出现tabbar或者navigationBar的。

topLayoutGuide无导航栏时,从y=状态栏高度开始。当然要说的一点是,iOS 7以及之后,状态栏都是透明的,所以在没有导航栏的时候,我们通常会将状态栏也视作可用范围,但一般只是填充颜色。当存在导航栏时,从y=状态栏高度+导航栏高度开始。这时导航栏会填充状态栏的背景色。

bottomLayoutGuide正常情况下,位于视图的最底部,也就是y=屏幕高度的位置。当存在tabbar时,它位于y=屏幕高度-tabbar高度的位置。

safe area代表的就是中间可用于布局的区域。以竖屏iPhone X为例:

  • 它不考虑tabbar和navigationBar的translucent
  • 状态栏高度44pt
  • 导航栏高度44pt,对,导航栏高度一直是44,不要被视觉骗了
  • tabbar高度49pt
  • 操作区,也就是以前的home键,高度是34pt,下文统一操作区称呼

当导航栏状态栏存在时,safe area 的frame是(0, 0, 375, 812-44-44-49-34=641)。
当导航栏存在时,safe area 的frame是(0, 0, 375, 812-44-44-34=690)。
当tabbar存在时,safe area 的frame是(0, 0, 375, 812-44-49-34=685)。
当两者皆不存在时,safe area 的frame是(0, 0, 375, 812-44-34=734)。

这个safe area就是我们可以随意布局的地方,就像之前的layout guide一样,其实两者没什么区别。只不过safe area用矩形来表达,更加明确。

屏幕的差异化

明确了解两种iPhone屏幕的不同是适配的前提,如下图:

这是我在Xcode 9Beta版分别跑的iPhone 8和iPhone X的模拟器,大家可以很清楚的看到二者的区别。首先,这个项目只是加了一个自定义的白色的view,背景色是橘黄色。其次,是在storyBoard中使用AutoLayout进行布局,白色view的约束是上下左右都是0。

从图上也可以看出,safe area的区域所占据的屏幕边缘是正常的矩形,也就是说苹果已经把椭圆边角的区域处理掉了,这就大大降低了布局的难度。当然,如果状态栏也被隐藏就需要特殊的设计以及布局了,另外下面那个操作区是没办法隐藏的。当你只在安全区布局时,完全可以像以前一样,不需要考虑任何边角问题。

成果

  • 当我们选择storyboard和xib布局时,我们都是在safe area中布局的
  • 当我们选择代码布局时,我们不能使用self.view.frame了,它会包含圆角区域
  • 我们在viewDidAppear中获取self.view.safeAreaLayoutGuide.layoutFrame,这个时候可以得到准确的safe area的frame
  • 而类似Mansory这种第三方布局框架,它们需要进行引入类似概念的升级了

项目地址

额外信息

  • iOS 11带来了ARKit和Core ML这两大框架
  • iPhone X指纹的移除
  • 系统的Push、Pop动画形式也发生了改变
  • Xcode中添加了更加利于重构的工具
  • 还有很多别的东西,大家慢慢玩,我相信会被苹果玩死的

查阅资料