前几天,随手记团队对 iPhone X 紧张的适配工作暂时告一段落。从最初在 iPhone X 模拟器上面运行,到最后真机测试时完全适配。在这一路过来适配的历程中,我们整理出下面这份通用的 iPhone X 适配文档供大家参考。
2、Always Remember
摘自 Designing for iPhone X : 为了让你的应用在 iPhone X上 面完美运行,你需要将可视元素扩展至填充整个展示窗口(屏幕)上,同时,你也需要保证如按钮、tab bar 等可交互控件,以及一些至关重要的信息不会因为屏幕的圆角而被裁掉,或者被手机的「刘海」和虚拟「Home键」遮住。
Updating your App to work on the new display(iPhone X) involves extending visual elements to fill the display's view port, while also keeping controls and critical information from getting clipped in the corners or covered by the sensor housing or home indicator.
3、UIKit and Auto Layout
对于原生的 UIKit 控件来说,适配 iPhone X 是一件非常轻松的事。假如你的应用使用了许多原生控件并且没有对它们做过多的自定义的话,例如像导航条 (Navigation Bars),列表 (Tables),集合视图 (Collection Views),这些控件会在 iPhone X 屏幕上自动调整其布局。
All apps should adhere to the safe area and layout margins defined by UIKit, which ensure appropriate insetting based on the device and context
The safe area also prevents content from underlapping the status bar, navigation bar, toolbar, and tab bar.
所有的应用应该附着于安全区域和 UIKit 定义的边距中,这可以让应用在各种设备或者横竖屏情况下都有正确的布局。同时,安全区域可以保证页面的内容不会和状态条、导航条、工具条或者底部导航重叠。
另一官方文档 Positioning Content Relative to the Safe Area 中的一张图清晰地展示了 safe area 在应用中代表的意义。
Standard system-provided views automatically adopt a safe area layout guide.
New in iOS 11, Apple is deprecating the top and bottom layout guides and replacing them with a single safe area layout guide。
另一个新的 API additionalSafeAreaInsets 则提供给开发人员能够自主扩展 safe area 区域的能力。顾名思义,如果对这个属性主动赋值,那么整个视图的 safe area 区域便会发生变化。
var additionalSafeAreaInsets: UIEdgeInsets { get set }
Use this property to adjust the safe area insets of this view controller's views by the specified amount. The safe area defines the portion of your view controller's visible area that is guaranteed to be unobscured by the system status bar or by an ancestor-provided view such as the navigation bar.
You might use this property to extend the safe area to include custom content in your interface. For example, a drawing app might use this property to avoid displaying content underneath tool palettes.
For the view controller's root view, the insets account for the status bar, other visible bars, and any additional insets that you specified using the additionalSafeAreaInsets property of your view controller.
对于 view controller 的根视图,SafeAreaInsets 会根据各种 bar 的高度,以及开发者自己设置的 additionalSafeAreaInsets 属性来计算。
其他:
For other views in the view hierarchy, the insets reflect only the portion of the view that is covered. For example, if a view is entirely within the safe area of its superview, the edge insets in this property are 0.
Home indicator 的设置类似于 prefersStatusBarStyle,iOS 11 增加了 UIViewController 的一个 UIHomeIndicatorAutoHidden 分类来控制 home 键的自动隐藏。通常在全屏播放视频,全屏游戏等场景下会需要用到此特性。
@interface UIViewController (UIHomeIndicatorAutoHidden)
// Override to return a child view controller or nil. If non-nil, that view controller's home indicator auto-hiding will be used. If nil, self is used. Whenever the return value changes, -setNeedsHomeIndicatorAutoHiddenUpdate should be called.
- (nullable UIViewController *)childViewControllerForHomeIndicatorAutoHidden API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);
// Controls the application's preferred home indicator auto-hiding when this view controller is shown.
- (BOOL)prefersHomeIndicatorAutoHidden API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);
// This should be called whenever the return values for the view controller's home indicator auto-hiding have changed.
- (void)setNeedsUpdateOfHomeIndicatorAutoHidden API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);
@end
需要注意 prefersHomeIndicatorAutoHidden,苹果官方并不确保这个重写这个方法一定可以让 home indicator 自动隐藏。
Discussion:
Override this method to signal your preference for displaying the visual indicator. The system takes your preference into account, but returning true is no guarantee that the indicator will be hidden.
值得一提的是,苹果并没有提供可以手动改变 home indicator 颜色的接口给开发者。因为苹果并不希望我们手动更改 home indicator 的颜色,而应该遵循其自动切换颜色的特性(Home indicator 会根据底色的不同自动切换黑色或白色)。