在探索Xcode9 Beta时,在Interface builders View hierarchy viewer上找到了Safe Area.我很好奇,想知道苹果公司文档中的安全区域,文件大意是"The the view area which directly interacts with Auto layout",但我不满意,我想知道这个新东西的实际用途.

有谁有线索吗?

enter image description here

Conclusion paragraph from Apple doc for Safe area.

UILayoutGuide类旨在执行以前由虚拟视图执行的所有任务,但要以更安全、更高效的方式执行.布局参考线不定义新视图.它们不参与视图层次 struct .相反,它们只是在自己视图的坐标系中定义一个可以与自动布局交互的矩形区域.

推荐答案

Safe Area is a layout guide (100).
表示视图中未被条形图和其他内容遮挡的部分的布局参考线.在iOS11+中,苹果放弃了顶部和底部的布局指南,取而代之的是单一的安全区域布局指南.

当视图在屏幕上可见时,本指南将反映未被其他内容覆盖的视图部分.视图的安全区域反映了导航栏、选项卡栏、工具栏和其他遮挡视图控制器视图的祖先所覆盖的区域.(在twOS中,安全区域包含屏幕的边框,由UIScreen的overscanCompensationInsets属性定义.)它还涵盖由视图控制器的additionalSafeAreaInsets属性定义的任何附加空间.如果视图当前未安装在视图层次中,或者在屏幕上尚不可见,则布局辅助线始终与视图的边缘匹配.

对于视图控制器的根视图,此属性中的安全区表示视图控制器内容的全部被遮挡部分,以及您指定的任何其他插入.对于视图层次中的其他视图,安全区域仅反映该视图中被遮挡的部分.例如,如果视图完全在其视图控制器的根视图的安全区域内,则此属性中的边缘插入为0.

据苹果称,Xcode 9 - Release note

在此处输入图像描述


以下是现有(顶部和底部)布局指南和安全区域布局指南之间的比较(以获得类似的视觉效果).

Safe Area Layout:

AutoLayout

在此处输入图像描述


How to work with Safe Area Layout?

请按照以下步骤查找解决方案:

  • 启用"安全区域布局",如果未启用.
  • 如果它们显示与Super view连接,则移除"所有约束",并使用安全布局锚点重新连接所有约束.或者双击约束并编辑从超级视图到安全区域锚点的连接

下面是示例快照,介绍如何启用安全区域布局和编辑约束.

在此处输入图像描述

以下是上述变化的结果

在此处输入图像描述


Layout Design with SafeArea
为iPhone X设计时,您必须确保布局充满屏幕,并且不会被设备的圆角、传感器shell 或用于访问主屏幕的指示器遮挡.

在此处输入图像描述

大多数使用系统提供的标准UI元素(如导航栏、表格和集合)的应用程序会自动适应设备的新外形.背景material 延伸到显示的边缘,并且UI元素被适当地插入和定位.

在此处输入图像描述

对于具有自定义布局的应用程序,支持iPhone X应该也相对容易,特别是如果您的应用程序使用Auto Layout并遵守安全区域和边距布局指南.

在此处输入图像描述


Here is sample code (Ref from: 100):
如果您在代码中创建约束,请使用UIView的safeAreaLayoutGuide属性获取相关的布局锚点.让我们用代码重新创建上面的Interface Builder示例,看看它是什么样子:

假设我们将绿色视图作为视图控制器中的属性:

private let greenView = UIView()

我们可能有一个函数来设置从viewDidLoad调用的视图和约束:

private func setupView() {
  greenView.translatesAutoresizingMaskIntoConstraints = false
  greenView.backgroundColor = .green
  view.addSubview(greenView)
}

一如既往地使用根视图的layoutMarginsGuide创建前导和尾随边距约束:

 let margins = view.layoutMarginsGuide
    NSLayoutConstraint.activate([
      greenView.leadingAnchor.constraint(equalTo: margins.leadingAnchor),
      greenView.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
 ])

现在,除非您仅针对iOS 11,否则您将需要使用#Available包装安全区域布局指南约束,并退回到较早iOS版本的顶部和底部布局指南:

if #available(iOS 11, *) {
  let guide = view.safeAreaLayoutGuide
  NSLayoutConstraint.activate([
   greenView.topAnchor.constraintEqualToSystemSpacingBelow(guide.topAnchor, multiplier: 1.0),
   guide.bottomAnchor.constraintEqualToSystemSpacingBelow(greenView.bottomAnchor, multiplier: 1.0)
   ])

} else {
   let standardSpacing: CGFloat = 8.0
   NSLayoutConstraint.activate([
   greenView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: standardSpacing),
   bottomLayoutGuide.topAnchor.constraint(equalTo: greenView.bottomAnchor, constant: standardSpacing)
   ])
}


结果:

在此处输入图像描述


UIView扩展之后,您可以轻松地以编程方式使用SafeAreaLayout.

extension UIView {

  // Top Anchor
  var safeAreaTopAnchor: NSLayoutYAxisAnchor {
    if #available(iOS 11.0, *) {
      return self.safeAreaLayoutGuide.topAnchor
    } else {
      return self.topAnchor
    }
  }

  // Bottom Anchor
  var safeAreaBottomAnchor: NSLayoutYAxisAnchor {
    if #available(iOS 11.0, *) {
      return self.safeAreaLayoutGuide.bottomAnchor
    } else {
      return self.bottomAnchor
    }
  }

  // Left Anchor
  var safeAreaLeftAnchor: NSLayoutXAxisAnchor {
    if #available(iOS 11.0, *) {
      return self.safeAreaLayoutGuide.leftAnchor
    } else {
      return self.leftAnchor
    }
  }

  // Right Anchor
  var safeAreaRightAnchor: NSLayoutXAxisAnchor {
    if #available(iOS 11.0, *) {
      return self.safeAreaLayoutGuide.rightAnchor
    } else {
      return self.rightAnchor
    }
  }

}

以下是Objective-C中的示例代码:


这是苹果开发者Safe Area Layout Guide年的官方文档


需要安全区来处理iPhone-X的用户界面设计.以下是How to design user interface for iPhone-X using Safe Area Layout人的基本指导方针

Ios相关问答推荐

SwiftUI文本编辑器内部滚动填充,无需文本裁剪

PieChartView未以编程方式显示在屏幕上

什么是最好的方式使用DateFormatters在可扩展视图cellForRowAt方法

更新@PersistableEnum时是否需要执行迁移块?

通过在SWIFT中不起作用的泛型传递协议一致性类型

设置托管在DigitalOcean上的iOS通用链接

带菜单的选取器不适用于Int32,但适用于Int

如何删除点击时按钮的不透明动画?

_SKStoreProductParameterAdNetworkSourceIdentifier未定义符号

@MainActor 类的扩展是主要演员吗?

为什么@FetchRequest 在删除时不更新和重绘视图?

错误:无法根据成员environmentObject推断上下文基础

将角半径仅应用于 Swiftui 中按钮的两个角

帧过渡动画有条件地工作

为什么我不能让 passthrough 科目为 combine 工作?

搜索在 ios xamarin.forms 中不起作用

如何 comments .plist 文件中的行?

ARKit vs. ARCore vs. Vuforia vs. D'Fusion Mobile vs. Layar SDK

aps-environment 始终在发展

如何为 NSDate 添加一个月?