在探索Xcode9 Beta时,在界面构建器视图层次结构查看器上找到了安全区。对Apples文档中的安全区感到好奇并试图了解,在要点中医生说“与自动布局直接交互的视图区域”,但它不满足我,我想知道这个新事物的实际应用。
有谁有线索吗?
结论段来自Apple的安全区.
UILayoutGuide类设计用于执行以前由虚拟视图执行的所有任务,但要以更安全、更有效的方式执行。布局指南不定义新视图。它们不参与视图层次结构。相反,他们只是在自己视图的坐标系统中定义了一个矩形区域,可以与自动布局交互。
发布于 2017-07-26 18:04:40
(安全区布局指南). 安全区是布局指南 表示视图中不被条形条和其他内容遮掩的部分的布局指南。在iOS 11+中,苹果不推荐顶部和底部的布局指南,取而代之的是单一的安全区布局指南。
当视图在屏幕上可见时,本指南反映视图中未被其他内容覆盖的部分。视图的安全区域反映了导航条、选项卡条、工具栏和其他祖先所覆盖的区域,这些祖先掩盖了视图控制器的视图。(在tvOS中,安全区包含由UIScreen的overscanCompensationInsets
属性定义的屏幕的边框。)它还涵盖视图控制器的additionalSafeAreaInsets
属性定义的任何附加空间。如果视图当前未安装在视图层次结构中,或尚未在屏幕上显示,则布局指南始终与视图的边缘匹配。
对于视图控制器的根视图,此属性中的安全区域表示视图控制器内容的全部模糊部分,以及您指定的任何附加嵌入。对于视图层次结构中的其他视图,安全区域只反映视图中模糊的部分。例如,如果一个视图完全位于其视图控制器根视图的安全区域内,则此属性中的边缘嵌入为0。
据苹果公司称,Xcode 9-发行说明 接口生成器使用UIView.safeAreaLayoutGuide作为UIViewController中不推荐的顶部和底部布局指南的替代品。若要使用新的安全区,请在“文件”检查器中为视图控制器选择“安全区布局指南”,然后在内容和新的安全区域锚点之间添加约束。这可以防止您的内容被顶部和底部栏以及tvOS上的过度扫描区域所遮蔽。当部署到早期版本的iOS时,安全区域的约束被转换为顶部和底部。
这里是一个简单的参考,作为比较(使类似的视觉效果)的现有(顶部和底部)布局指南和安全区布局指南。
安全区布局:
AutoLayout
如何处理安全区域布局?
按照以下步骤找到解决方案:
下面是示例快照,如何启用安全区布局和编辑约束。
以下是上述更改的结果
基于 SafeArea的版图设计
在为iPhone X设计时,您必须确保布局填充屏幕,并且不会被设备的圆角、传感器外壳或访问主屏幕的指示器所遮挡。
大多数使用标准的、系统提供的UI元素(如导航条、表和集合)的应用程序都会自动适应设备的新形式因素。背景材料延伸到显示的边缘,UI元素被适当地嵌入和定位。
对于具有自定义布局的应用程序,支持iPhone X也应该相对容易,特别是如果您的应用程序使用自动布局,并遵循安全区域和边缘布局指南。
这里是示例代码(参考来源:安全区布局指南)::)
如果在代码中创建约束,请使用UIView的UIView属性获取相关的布局锚点。让我们在代码中重新创建上面的Interface示例,看看它的外观:
假设我们在视图控制器中将绿色视图作为属性:
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,否则需要将安全区布局指南约束包装为可用#,并返回到早期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中的示例代码
以下是苹果开发人员关于安全区布局指南的官方文档
需要安全区域来处理iPhone的用户界面设计。以下是如何使用安全区域布局设计iPhone的用户界面的基本指导方针
发布于 2017-09-15 05:58:24
--我想提到的是,当我试图调整一个基于SpriteKit的应用程序以避免新的iPhone X的圆角和“凹槽”时,我首先想到的是一些东西,正如最新的人机界面指南所建议的:在将视图添加到层次结构(例如,-viewDidAppear:
)之后,需要查询新的属性safeAreaLayoutGuide
of UIView
,以报告一个有意义的布局框架(否则,它只返回全屏大小)。
从财产的文件:
表示视图中不被条形条和其他内容遮掩的部分的布局指南。当视图在屏幕上可见时,本指南反映视图中未被导航条、选项卡条、工具栏和其他祖先视图覆盖的部分。(在tvOS中,安全区反映未覆盖屏幕边框的区域。)如果视图目前没有安装在视图层次结构中,或者在屏幕上尚未可见,则布局指南边缘与视图的边缘相等。
(强调地雷)
如果您早在-viewDidLoad:
上阅读它,指南的layoutFrame
将是{{0, 0}, {375, 812}}
而不是预期的{{0, 44}, {375, 734}}
。
发布于 2017-10-10 11:28:08
UIKit
使用了topLayoutGuide & bottomLayoutGuide,即UIView
属性UIView
属性。UIButton
等。print(UIApplication.shared.statusBarFrame.height)//44 for iPhone X, 20 for other iPhones
时不会更改高度
您可以将约束与self.view.safeAreaLayoutGuide
的各自设置为-
ObjC:
self.demoView.translatesAutoresizingMaskIntoConstraints = NO;
UILayoutGuide * guide = self.view.safeAreaLayoutGuide;
[self.demoView.leadingAnchor constraintEqualToAnchor:guide.leadingAnchor].active = YES;
[self.demoView.trailingAnchor constraintEqualToAnchor:guide.trailingAnchor].active = YES;
[self.demoView.topAnchor constraintEqualToAnchor:guide.topAnchor].active = YES;
[self.demoView.bottomAnchor constraintEqualToAnchor:guide.bottomAnchor].active = YES;
Swift:
demoView.translatesAutoresizingMaskIntoConstraints = false
if #available(iOS 11.0, *) {
let guide = self.view.safeAreaLayoutGuide
demoView.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
demoView.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
demoView.bottomAnchor.constraint(equalTo: guide.bottomAnchor).isActive = true
demoView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
} else {
NSLayoutConstraint(item: demoView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: demoView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: demoView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: demoView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
}
https://stackoverflow.com/questions/44492404
复制相似问题