这是一个故事:
故事背景
iPhone X 刘海机于9月份发布以来,备受诟病,给科技带来一个宴会.给coder却带来一份淡淡的凉意---> 怎么适配呢?
我们的APP会不会被遮住,多出来一个刘海? 我们底下的Tabbar会变成什么样? Home键去哪了?
据说WWDC大会上给出了适配建议,打开看了(好吧,我承认我听不懂).最近项目需要做适配,就在网上搜集了一些资料,总结一下,放在这里.供大家参考.
先看看iPhone各机型的尺寸吧.
下面是iPhone X 对比其他机型的变化图.iPhone X和iPhone 8 在宽度上是一致的,在垂直方向上多出了145pt,这就意味着首页可以展示更多的内容,这对于一些大IP来说可能是一个巨大的价值,但是对于众多小众APP来说,我们还是关心适配的问题吧.
布局
如上图所示,我们会发现,刘海会遮住我们的视图控件,所以我们设计的时候要避免关键内容被遮盖.
iPhone X可以展示的区域以及坐标系统如下图:
Status Bar 状态栏
我们用系统的navigationBar会发现,它会自动变高,如下图所示.其实是上面原先20pt的Status Bar变高了,我们通过打印Status Bar的frame可以发现,它变成了44pt.
住:如果你的APP是隐藏状态栏的,建议重新考虑,首先,状态栏包含了用户想要的信息,其次,如果隐藏了,你的上边的刘海两侧的空白会很难看
另外还有一点,用户在使用 iPhone X 打电话的时候,StatusBar 的高度也不会发生变化了。
底部区域
iPhone X取消了Home键,但是苹果公司给用户流出来一个一个叫做Home Indicator的区域,在这个区域,你向上滑动,就等同于原来点击了Home键,就会回到手机桌面. 这部分的高度是固定的--34pt.(除了iPhone X,其他手机没有这个区域,因为Home键还在).
如果你的底部是 TabBar,那么 Home Indicator 背景会来自于 TabBar 背景的延伸,如果我们是一个 feed 流的页面,那么底部会展示 feed 流的局部。意思是如果有 TabBar,那么那个区域会延展你的 barTintColor;没有的话,就显示透明的(参照 Setting)。之所以这么设计,是为了让 indicator 清晰可见,告诉用户你可以滑动这部分区域。所以苹果不建议我们的 UI 元素过于靠近这部分区域。
SafeArea --> 安全区域
这个是很坑的一个地方.
iOS 11 废弃了 iOS 7 之后出现的 topLayoutGuide/bottomLayoutGuide,取而代之的是safeLayoutGuide 概念。我们的UI元素都应该布局在这些区域之内,避免被各种 bar(NavgationBar、ToolBar、TabBar、StatusBar)遮挡。
如果我们用了 AutoLayout,并且开启了 safeAreaLayoutGuide,布局会自动加上这些 safeLayoutGuide,你的视图不会超出这部分 SafeArea。如下图所示,如果你需要增加 Guide 的区域,那么可以设置 self.additionalSafeAreaInsets 来增加区域。
默认的 SafeArea 和 self.additionalSafeAreaInsets = UIEdgeInsetsMake(64, 0, 0, 0);
刘海打理
- 我们的页面大多会上移,这属于于“状态栏变高系列”,解决方案就是把固定的20pt高度改成 [[UIApplication sharedApplication] statusBarFrame].size.height]。
2 搜索页面输入框的位置发生了偏移,这是因为 iOS 11 的导航栏的视图层级结构发生了变化,和 iPhone X 的并无直接关系。iOS 11 导航栏的视图层级关系如下:
适配方式是:取到这个 _UIButtonBarStackView 的位置和尺寸信息,然后更改 PFBNavigationBarContainerView 的 X 坐标。
- iOS 11 之后 scrollview 多出来一个 adjustedContentInset 区域。UItableView 会发生偏移.那为什么会发生偏移?这个偏移的值又是怎么确定的?其实是当 Tableview 的 frame 超出了 safeArea 范围之后,系统会调整内容的位置。系统通过设置 adjustedContentInset 为 safeAreaInset 的值让 Tableview 偏移.注意一下这个 adjustedContentInset 是 readOnly 的属性。我们可以通过设置 Tableview.contentInsetAdjustmentBehavior=UIScrollViewContentInsetAdjustmentNever 来纠正这个位置。当然还可以通过设置 tableview.contentOffset 来抵消这个值,但还是推荐第一种。
iOS 11的适配
① xib 里适配 iPhone X 的话,可以开启 UseSafeAreaLayoutGuides(但是这个是需要在 iOS 9 之后才能用,需要看你的 App 最低支持的版本)。
2.如果用的系统 SearchViewController,发现没有灰色蒙层了,可以这么试试。之所以可以这么改,是因为 iOS 11 的 NavigationBar 和 SearchViewController 集成在一块儿了。
-
横屏下的 UITableView,SenctionHeader 的背景颜色不是设置的那个颜色。
这个问题的原因是:横屏下的 UITableView,Cell 都是和屏幕一样宽,但是 Cell 的 ContentView 会被 inset 到 SafeArea 区域。
解决方法是:可以通过调整 Tableview 的默认行为,改变 contentView 的属性(如上图 inset To SafeArea)来让 contentview 顶到边缘,弊端是会改变整个 cell 的内容显示,而且 contentView 的 layoutMargin 依然还是相对于 SafeArea 的。
最佳方案是:改变 UITableViewHeaderFooterView.backgroundView 的 backgroundColor。
本文章转自美团点评的一篇文章 和一些博客.
最后总结:
1.状态栏高度发生变化,解决方案:布局的时候这个高度不要写死,通过方法获取高度.
2.导航栏的视图层级结构发生变化而导致 UI(titleView、UIBarButtonItem) 问题。
3.safeAreaInset 导致 Scrollview 偏移。
4.Tabbar发生变化,建议用系统的tabbar.
如何把文章排版变得更好看,点击:Markdown使用指南(常用语法,干货).