似乎有几个不同的选项/术语,iOS社区中的人使用布局(例如,UIEdgeInsets是一种类型,但有时我会听到/读取“设置插图”或布局边距与布局指南)。
我一直能找到一个有效的选项。但我不确定我是否正在使用合适的工具。
有人可以帮助在布局的这些不同方面之间提供一些清晰度,以及何时以最佳方式使用每个方面?
答案 0 :(得分:25)
作为赏金提供者......我说我的大多数困惑来自于对UILayoutGuide
课程的正确理解。这很关键,但也很简单。
我先介绍一下problem:
在过去,如果你需要像这样限制这些圈子:
然后你必须创建清除 UIViews并将它们添加为子视图,然后将约束添加到它们中,如下所示:
今天,您不需要将它们添加为子视图。你可以改为
要创建布局指南,您必须执行以下步骤:
addLayoutGuide(_:)
方法将布局指南添加到视图中。步骤进行:
let space1 = UILayoutGuide()
view.addLayoutGuide(space1)
let space2 = UILayoutGuide()
view.addLayoutGuide(space2)
space1.widthAnchor.constraintEqualToAnchor(space2.widthAnchor).active = true
saveButton.trailingAnchor.constraintEqualToAnchor(space1.leadingAnchor).active = true
cancelButton.leadingAnchor.constraintEqualToAnchor(space1.trailingAnchor).active = true
cancelButton.trailingAnchor.constraintEqualToAnchor(space2.leadingAnchor).active = true
clearButton.leadingAnchor.constraintEqualToAnchor(space2.trailingAnchor).active = true
布局指南也可以作为黑盒子,包含许多其他视图和控件。这使您可以封装部分视图,将布局分解为模块化块。
三个有趣的笔记:
UILayoutGuide
有关详情,请参阅documentation。
topLayoutGuide
与safeAreaLayoutGuide
它已被弃用,但出于学习目的:UIViewController
有2个虚拟框。顶部的1个属性名为topLayoutGuide
,另一个属性名为bottomLayoutGuide
。 viewController本身没有左/前或右/尾侧的任何指南。这两个都是UILayoutGuide
如果约束到view.topAnchor即:
tableView.topAnchor.constraint(equalTo: view.topAnchor)
tableView 不会从navigationBar底部开始
如果约束为topLayoutGuide.bottomAnchor
,即:
tableView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor)
根据您的布局设计,您可能希望在导航栏下方模糊您的内容。
我们的想法是,您可以边缘地展示自己的内容。和 它会使酒吧重叠,这样你就可以得到这些漂亮的彩色 通过栏目模糊你的内容
有关详情,请参阅此moment from WWDC和此问题here。我不认为解决方案是完全相关的,只是问题中的图像。
自iOS11 以来
Apple已弃用
topLayoutGuide
&bottomLayoutGuide
。所以 而不是有2个虚拟盒子,你现在有一个名为的虚拟盒子 UIView实例上的safeAreaLayoutGuide
。 UIViewController不再有任何这个...... 从useyourloaf复制的视觉比较:
旁注:如果您使用故事板,那么将您的视图与topLayoutGuide或safeAreaLayoutGuide顶部对齐将呈现相同的效果。如果您不使用故事板(以编程方式进行),那么您必须在iOS11和LessThaniOS11之间跳舞并拥有2个不同版本的代码
有关safeAreaLayoutGuide
的更多信息,我高度建议您设置Apple's article on: Positioning Content Relative to the Safe Area
注意: safeAreaLayoutGuide
是UIView属性。 topLayoutGuide
是UIViewController属性。
layoutMarginsGuide
UIView
只有一个虚拟框。该属性名为layoutMarginsGuide
。但与UIViewController
不同的是,它并不位于顶部或底部。它只是位于中心,有8个点填充/插入(从所有4个边)到UIView
。那么这在哪里有用?:如果你你会使用它>不要希望将textView约束到UIView实例的边缘。这将改善阅读体验。或者不是将按钮限制在其超级视图的leadingAnchor并使其看起来很丑,而是向锚点添加8个点...即将按钮约束到leadingAnchor然后添加8个常量点。 严格的文字,实际上是您使用readableContentGuide
的地方,layoutMarginsGuide
非常有用,如果您不希望按钮或标签锚定超级视图的边缘
someButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8)
但等待有一种更简单的方法。只需使用Apple建议的保证金即使用:
someButton.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor)
另请参阅提供的示例 documentation。 可以找到一个很好的Raywenderlich教程 here
readableContentGuide
与layoutMarginGuide
略有不同。两者都是UIView的属性。有时它们是相同的,有时它们不是。它的目的是:
此布局指南定义了一个可以轻松读取的区域 强迫用户移动他们的头来跟踪线
有关详情,请参阅this moment from WWDC: building Adaptive layout和这个真棒useyourloaf tutorial。
在纵向iPhone 7 Plus上,可读内容指南是相同的 作为视图的边缘指南,但在景观中有更多的白色 文本视图两侧的空格。在iPad上的风景, 白色空间显着增加。
边距大小取决于系统的动态类型。越大了 字体,指南会越宽。
在下面的图片中,青色固定在layoutMarginGuide
上,但绿色固定在readableContentGuide
上:
UIEdgeInsets
如果您想更改layoutMarginsGuide
即将所需的保证金从8点更改为16点,则必须更改layoutMargins
的值,然后更改layoutMarginsGuide
& #39; s anchors 会自动更新。
UIEdgeInsets
只是layoutMargins
的类型。 layoutMargins
是UIView
类
someview.layoutMargins = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)
我发现此代码唯一的地方☝️在viewDidLayoutSubviews
内有效。有关详情,请参阅here
Anchors
他们是基础但没什么特别之处。它们是任何UIView / UILayoutGuide的最远边缘。 UIView和UILayoutGuide实例都有它。 一切你的约束最终会被使用锚点限制,这只是你正在锚定它的实体的锚点的问题。它可以是safeAreaLayoutGuide
的锚点,也可以是layoutMarginGuide
的锚点,它可以是topLayoutGuide
的锚点,也可以是view
的锚点。layoutMarginsGuide
&#39}一个Anchors
的锚点。 (虽然你也可以将你的heightAnchor锚定到50,所以在这种情况下,没有另一个锚点)
safeAreaLayoutGuide
和layoutMarginGuide
之间的精彩视觉比较可以从answer找到。它使用故事板完成,因此更容易理解。
contentInsets
虽然理解很重要,但这是一个完全不同的讨论,与其他人没有任何关系。它特定于UIScrollViews。有关详情,请参阅this great article
为确保安全,确保所有内容 您的视图使用readableContentGuide
。如果您想使用系统提供的边距来获得更好的视图布局或者使用一些填充,请使用readableContentGuide
,如果您想让事情更具可读性layoutMarginGuide
。
layoutMarginGuide
的大小始终小于或等于safeAreaLayoutGuide
layoutMargins
的大小始终小于或等于safeAreaLayoutGuide
readableContentGuide
与CSS的填充非常相似。 contentInset
类似于CSS边框。我不知道contentOffset
它们用于scrollViews,与答案的其余部分有些无关。关于contentSize
& contentSize
是{{1}},请参阅this moment from WWDC 2018: UIKit: Apps for Every Size and Shape
。视频非常简单。另请参阅下面的Karthik的答案。有这样说,你完全理解scrollView如何工作并理解{{1}}是什么是至关重要的,否则它会很复杂。有关{{1}}和scrollView的更多信息,请参阅Vacawama's answer here
答案 1 :(得分:5)
我希望您能从以下链接/图片中获取信息。
您可以从以下链接推断出布局参数所需的信息。
答案 2 :(得分:0)
很抱歉,如果这是一个无聊的答案,但我觉得Apple Developer文档非常擅长描述如何使用每个UIView属性。
当你有多个方法/选项有效时,实现布局的最佳方法是什么......这真的是一个风格/意见的问题。我将专注于以下标准来做出决定:
团队可以通过这个标准共同努力,就我们如何布局我们的UI"在每个场景中。我想你要求的是这种讨论的总和产品:各种布局风格的指南。
根据我的经验,这一直是我所参与过的团队的有机发展,事情并没有真正写下来。在上面的第3点之后还有更多的内容。
Apple文档中针对问题中描述的类的一些摘录:
使用布局指南替换您可能已创建的虚拟视图,以表示用户界面中的视图间空间或封装。传统上,有许多自动布局技术需要虚拟视图。
...
UILayoutGuide类旨在执行以前由虚拟视图执行的所有任务,但要以更安全,更有效的方式执行。
在iOS 11及更高版本中,使用directionalLayoutMargins属性指定布局边距而不是此属性。
使用此属性指定此视图及其子视图边缘之间所需的空间量(以磅为单位)。根据当前布局方向,前沿和尾随边距适当地应用于左边距或右边距。
在contentInset上:
使用此属性可扩展内容与内容视图边缘之间的空间。单位是点。默认值为UIEdgeInsetsZero。
在topAnchor上:
上使用此锚点可以使用视图的上边缘创建约束。您只能将此锚点与其他NSLayoutYAxisAnchor锚点组合使用。有关更多信息,请参阅NSLayoutAnchor。
使用这些约束以编程方式使用“自动布局”定义布局。不是直接创建NSLayoutConstraint对象,而是从您想要约束的UIView,NSView或UILayoutGuide对象开始,并选择该对象的锚属性之一。这些属性对应于Auto Layout中使用的主要NSLayoutConstraint.Attribute值,并提供适当的NSLayoutAnchor子类以创建对该属性的约束。使用anchor的方法来构造约束。