在 iOS 7 Apple 在 UIViewController 中引入了 topLayoutGuide
和 bottomLayoutGuide
属性来描述没有被覆盖(status bar, navigation bar, toolbar, tab bar, etc.)屏幕的区域。在 iOS 11 中,Apple 已经弃用了这些属性,并引入了 safe area。Apple 建议我们不要在 safe area 操作,在 iOS 11 中,当在 iOS App 中定位视图时,你必须使用新的 safe area API。
UIView
在 iOS 11 UIViewController topLayoutGuide
和 bottomLayoutGuide
属性已经被替换成了新的 UIView 中的 safe area:
@available(iOS 11.0, *) |
safeAreaInsets
属性意味着屏幕可以覆盖从四个方向,而不仅仅是顶部和底部。当被 iPhone X 呈现时,我们就明白了为什么我们需要左右 insets。
iPhone 8 vs iPhone X safe area (portrait orientation)
iPhone 8 vs iPhone X safe area (landscape orientation)
iPhone X 在 portrait orientation 有 top 和 bottom 的 safe area,在 landscape orientation 有 left right 和 bottom。
让我们来看一个例子。在 ViewController 的 View 的顶部和底部添加了两个带有文本标签和固定高度的 custom subviews,并附加 attached 到视图的边缘 edges。
Subviews are attached to the view’s edges
正如所看到的,subviews 内容与顶部的 notch 和底部的 home indicator 指示器重叠 overlapped。为了正确地定位 subviews,我们可以使用手动布局将它们附加到 safe area:
topSubview.frame.origin.x = view.safeAreaInsets.left |
或者使用 Auto Layout:
bottomSubview.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true |
Subviews are attached to the superview safe area
上面看起来好很多。此外可以在 subview subclass 添加 subviews content 到 safe area。
Subviews are attached to the view’s edges. Labels are attached to the superview safe area.
在 subviews 层次结构 hierarchy 的任何地方都可以将 view 添加到 safe area。
UIViewController
在 iOS 11 UIViewController 有了一个新属性:
@available(iOS 11.0, *) |
当 view controller subviews 覆盖嵌入的 child view controller views 时,将使用它。例如,Apple 在 UINavigationController 和 UITabBarController 中使用额外的 additional safe area insets,当这些条是半透明的。
additionalSafeAreaInsets
是对现有 safearea 的扩展附加。
当你改变 additional safe area insets 或者 safe area insets 被系统改变,UIView 和 UIViewController 中的方法将被调用:
// UIView |
Simulate iPhone X safe area
Additional safe area insets 也可以用来测试你的 app 是如何支持 iPhone X,如果你不能在模拟器上测试你的 app,而且没有 iPhone X,那就很有用了。
//portrait orientation, status bar is shown |
UIScrollView
待续