iPhone X 适配(全)

背景

iPhone X 刘海机于9月13日发布,给科技小春晚带来一波高潮。做为开发人员却多出来一份忧虑,iPhone X 怎么适配?咱们 App 的脑壳会不会也长一刘海出来?Tabbar 会不会被圆角?先来看一下美团 App 的表现:html

图 1.1 启动时的 App 表现           图 1.2 下拉刷新以后的表现ios



图 1.3 搜索的表现          图 1.4 “个人Tab”表现session

在图1.1中乍一看表现还不错,但是在图1.2中,下拉刷新以后,咱们的导航栏仍是被刘海挡住了。搜索也中枪,搜索首页没有办法取消,“热门搜索区域”也多出来一起空白。另外,“个人Tab”页部分如图1.三、图1.4所示,导航栏回不去了,右上角的三个UIBarButtonItem也不见了。其余还有不少UI上的Bug,等着咱们去一一发现并修改。app

针对可能出现的问题,苹果在 developer.apple.com 上给出了一些建议。其中一个是 HIG (Human Interface Guideline)。另外 WWDC 会议官方 App 的做者,也给出了适配时的一些经验iphone

咱们来看看他们是怎么说的。ide

HIG部分

首先看一下各个机型尺寸的变化。布局

图 2.1 各版本 iPhone 的尺寸ui

下图是 iPhone X 对比其余机型的变化部分。iPhone X 和 iPhone 8 的宽度一致,在垂直方向上多了145pt,这就意味着首页能够展现更多的内容,多出来的这20%的垂直空间,也许能够挂上更高价值的运营位。this

图2.2 iPhone X 和其余设备的尺寸对比spa

布局

注意图2.2蓝色部分,你会发现这些都算在了展现内容的区域。因此咱们在设计的时候,要避免内容被圆角、刘海给挡住。Like this:

图 2.3 CGRectMake(0,0,100,100)

iPhone X 的坐标系统以及能显示内容的区域以下图所示:

图 2.4 iPhone X 的显示区域

Status Bar

iPhone X 上的 StatusBar 高度比以前的 iPhone 高一些,也就是说,咱们若是写死20pt高度的 frame 布局,都要大面积修(tu)改(xue)。在 iPhone X 上,经过打印 [[UIApplication sharedApplication] statusBarFrame] 能够看到,高度是44pt。

图 2.5 iPhone X 的状态栏高度

"若是你的 App 是隐藏 StatusBar 的,建议从新考虑。iPhone X 为用户在垂直空间上提供了更多展现余地,且状态栏中也包含了用户须要知道的信息,除非能经过隐藏状态栏带给用户额外的价值,不然苹果建议你们将状态栏还给用户。"

另外还有一点,用户在使用 iPhone X 打电话的时候,StatusBar 的高度也不会发生变化了。

屏幕底部

由于没有了 Home 键,iPhone X 的底部是预留给系统功能的一个区域 - Home Indicator,这部分的高度是34pt。

图 2.6 iPhone X 的 Home Indicator 区域

“若是你的底部是 TabBar,那么 Home Indicator 背景会来自于 TabBar 背景的延伸,若是咱们是一个 feed 流的页面,那么底部会展现 feed 流的局部。”

意思是若是有 TabBar,那么那个区域会延展你的 barTintColor;没有的话,就显示透明的(参照 Setting)。之因此这么设计,是为了让 indicator 清晰可见,告诉用户你能够滑动这部分区域。因此苹果不建议咱们的 UI 元素过于靠近这部分区域。

图 2.7 有 TabBar 的 Home Indicator 区

SafeArea

iOS 11 废弃了 iOS 7 以后出现的 topLayoutGuide/bottomLayoutGuide,取而代之的是safeLayoutGuide 概念。咱们的UI元素都应该布局在这些区域以内,避免被各类 bar(NavgationBar、ToolBar、TabBar、StatusBar)遮挡。

图2.8 iPhone 的 SafeArea

若是咱们用了 AutoLayout,而且开启了 safeAreaLayoutGuide,布局会自动加上这些 safeLayoutGuide,你的视图不会超出这部分 SafeArea。如2.9所示,若是你须要增长 Guide 的区域,那么能够设置 self.additionalSafeAreaInsets 来增长区域。

图 2.9 默认的 SafeArea 和 self.additionalSafeAreaInsets = UIEdgeInsetsMake(64, 0, 0, 0);

其余

还有其余的一些改变,好比图片的 Aspect Ratio 在 iPhone X 上的表现也会有所不一样了;

刘海两边的区域都能响应不一样的手势,最好不要和本身的 App 发生冲突。

来自Session 201的建议

① xib 里适配 iPhone X 的话,能够开启 UseSafeAreaLayoutGuides(但这须要在 iOS 9 以后才能用,须要看你的 App 最低支持的版本)。


图3.1 xib 属性

② 若是用的系统 SearchViewController,发现没有灰色蒙层了,能够这么试试。

图3.2 iOS 11 UISearchViewController适配

之因此能够这么改,是由于 iOS 11 的 NavigationBar 和 SearchViewController 集成在一起了。

③ 横屏下的 UITableView,SenctionHeader 的背景颜色不是设置的那个颜色。

图3.3 iOS 11 横屏 Tableview 的做用方式

这个问题的缘由是:横屏下的 UITableView,Cell 都是和屏幕同样宽,可是 Cell 的 ContentView 会被 inset 到 SafeArea 区域。
解决方法是:能够经过调整 Tableview 的默认行为,改变 contentView 的属性(如上图 inset To SafeArea)来让 contentview 顶到边缘,弊端是会改变整个 cell 的内容显示,并且 contentView 的 layoutMargin 依然仍是相对于 SafeArea 的。
最佳方案是:改变 UITableViewHeaderFooterView.backgroundView 的 backgroundColor。

图3.4 iOS 11 修改先后的样式对比

刘海打理初体验

① 咱们来看下开头说的那个刷新以后首页顶上去的问题怎么处理。通过排查,这个问题属于“状态栏变高系列”,解决方案就是把固定的20pt高度改为 [[UIApplication sharedApplication] statusBarFrame].size.height]

② 搜索页面输入框的位置发生了偏移,这是由于 iOS 11 的导航栏的视图层级结构发生了变化,和 iPhone X 的并没有直接关系。iOS 11 导航栏的视图层级关系以下:

图4.1 iOS 11 以后的 NavigationBar     图4.2 iOS 11 以前的 NavigationBar

适配方式是:取到这个 _UIButtonBarStackView 的位置和尺寸信息,而后更改 PFBNavigationBarContainerView 的 X 坐标。

③ “个人Tab” 页面多出来一起灰色的区域,通过排查发现这个是 Tableview 的背景色。也就是说实际上是 Tableview 向下偏移了。

图4.3 iOS11 下“个人Tab” 页面 Tableview 发生偏移

出现这个的缘由是:iOS 11 以后 scrollview 多出来一个 adjustedContentInset 区域。

图 4.4 iOS 11下 ScrollView 的新属性

经过打印这个值,咱们发现正好和 contentoffset.y 相符合。

图 4.5 这个新属性在 iPhone X 上的值

那为何会发生偏移?这个偏移的值又是怎么肯定的?实际上是当 Tableview 的 frame 超出了 safeArea 范围以后,系统会调整内容的位置。系统经过设置 adjustedContentInset 为 safeAreaInset 的值让 Tableview 偏移

图 4.6 iPhone X 上 safeAreaInset 的值

注意一下这个 adjustedContentInset 是 readOnly 的属性。咱们能够经过设置 Tableview.contentInsetAdjustmentBehavior=UIScrollViewContentInsetAdjustmentNever 来纠正这个位置。固然还能够经过设置 tableview.contentOffset 来抵消这个值,但仍是推荐第一种。

④ “个人Tab” 导航栏上,右边那个按钮全都发生了偏移,致使没法点击。这个问题也是在新的导航栏结构视图下会出现,缘由是新的导航栏结构用了 AutoLayout 布局,咱们这个并非用常规的 UIBarButtonItem 方式实现的,而是一个 UIBarButtonItem ,他的 customView 包含了三个 Button,这几个 Button 都是 frame 布局,从而致使了在 AutoLayout 下的布局问题。

正常的解决方式是:修改为一个一个添加 UIBarButtonItem 和 UIBarButtonSystemItemFixedSpace。可是这样引出来另一个问题,iOS 11 以前那种设置负宽度的 fixedspace 来调整间距的 trick 方式已经失效了!详情见https://forums.developer.apple.com/thread/80075

咱们这边的方式是:依然用那种一个 CustomView 里包含三个 CustomButton 的方式,而后分别加上约束。CustomView 只须要加上宽高,包含的 Button 加上 left、top 和 size。

图 4.7 加约束修正后样式

如下是尝试修复这部分问题的代码:

// offset 问题
if (@available(iOS 11.0, *)) {
        self.contentViewController.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
// UIBarButtonItem 问题
if (@available(iOS 11.0, *)) {
        [messageButtonsContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.size.mas_equalTo(CGSizeMake(themeButton.width + settingButton.width + messageButton.width, 44));
        }];
        [themeButton mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(messageButtonsContainerView);
            make.left.equalTo(messageButtonsContainerView);
            make.size.mas_offset(CGSizeMake(44, 44));
        }];
        [settingButton mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(messageButtonsContainerView);
            make.left.equalTo(themeButton.mas_right);
            make.size.mas_offset(CGSizeMake(44, 44));
        }];
        [messageButton mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(messageButtonsContainerView);
            make.left.equalTo(settingButton.mas_right).offset(-10);
            make.size.mas_offset(CGSizeMake(44, 44));
        }];
    }

    UIBarButtonItem *rightBarItem = [[UIBarButtonItem alloc] initWithCustomView:messageButtonsContainerView];
    self.navigationItem.rightBarButtonItems = @[rightBarItem];

总结

当前发现这些问题的环境是 Xcode 9 GM版本(9A235)的模拟器。归结起来是三类问题:

  1. StatusBar 变高而且绝对布局。
  2. 导航栏的视图层级结构发生变化而致使 UI(titleView、UIBarButtonItem) 问题。(iPhone 6s iOS 11 上依然是旧的结构,是由于如今 AppStore 上的包依然是用 iOS 10 的 SDK 打出来的)。
  3. safeAreaInset 致使 Scrollview 偏移。

至于 Tabbar ,由于咱们用的是系统的,因此目前并无发现什么奇怪的地方。但愿咱们踩的这些坑可让各位在适配的过程当中少走一些弯路!

 

源:https://tech.meituan.com/iPhoneX%E5%88%98%E6%B5%B7%E6%89%93%E7%90%86%E6%8C%87%E5%8C%97.html

相关文章
相关标签/搜索