在iOS上,页边距,边缘插图,内容插图,对齐矩形,布局页边距,锚点之间有什么区别? [英] On iOS, what are the differences between margins, edge insets, content insets, alignment rects, layout margins, anchors...?
问题描述
关于布局,iOS社区中似乎有几种不同的选项/术语和人们使用(例如,UIEdgeInsets是一种类型,但有时我会听到/读到设置插图"或布局边距与布局指南).
There seem to be several different options/terms and people in the iOS community use with respect to layout (e.g. UIEdgeInsets is a type, but sometimes I hear/read "set the insets" or layout margins vs layout guides).
我一直都能找到一个可行的选项.但是我永远不能确定我使用正确的工具来完成这项工作.
I've always been able to find an option that works. But I'm never sure that I'm using the right tool for the job.
有人可以帮助您清楚地了解布局的这些不同方面以及何时以最佳方式使用它们吗?
Can someone help provide some clarity between these different aspects of layout and when to use each in the best way?
推荐答案
Being the Bounty offerer...I'd say the majority of my confusion came from not properly understanding the UILayoutGuide
class. That is key, but also very simple.
首先让我介绍一个问题:
在过去,如果您需要像这样限制这些圈子:
In the old days, if you needed to constrain these circles like this:
然后,您必须创建 clear UIViews并将其添加为子视图,然后向其添加约束,如下所示:
Then you had to create clear UIViews and add them as your subviews and then add your constraints to them like below:
今天,您无需将它们添加为子视图.您可以改为使用
Today you don't need to add them as your subviews. You could instead just use
要创建布局指南,您必须执行以下步骤:
To create a layout guide, you must perform the following steps:
- 实例化一个新的布局指南.
- 通过调用视图的
addLayoutGuide(_:)
方法将布局指南添加到视图. - 使用自动布局"定义布局指南的位置和大小. 您可以使用这些指南来定义布局中元素之间的空间.以下示例显示了用于在一系列视图之间定义相等间距的布局指南.
- Instantiate a new layout guide.
- Add the layout guide to a view by calling the view’s
addLayoutGuide(_:)
method. - Define the position and size of the layout guide using Auto Layout. You can use these guides to define the space between elements in your layout. The following example shows layout guides used to define an equal spacing between a series of views.
步骤:
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
布局指南还可以充当黑匣子,其中包含许多其他视图和控件.这样一来,您可以封装部分视图,将布局分为模块化的块.
Layout guides can also act as a black box, containing a number of other views and controls. This lets you encapsulate part of your view, breaking your layout into modular chunks.
三个有趣的注释:
- 如果您使用的是视图调试层次结构",那么您会看到
UILayoutGuide
的更多实例
- 就像UIView一样,UILayoutGuide 实例具有所有种锚点
- 关于为什么不只创建虚拟UIView并完成创建UILayoutGuides的原因:将虚拟视图添加到视图层次结构会带来许多成本.首先,创建和维护视图本身存在成本.其次,虚拟视图是视图层次结构的完整成员,这意味着它为该层次结构执行的每个任务增加了开销,最重要的是,不可见的虚拟视图会拦截旨在发送给其他视图的消息,从而导致很难解决的问题找到."
- If you are using the 'view debug hierarchy' then you would be seeing more instances of
UILayoutGuide
- Just like a UIView, a UILayoutGuide instance has all kinds of anchors
- As for why not just create dummy UIViews and going through creating UILayoutGuides: "There are a number of costs associated with adding dummy views to your view hierarchy. First, there is the cost of creating and maintaining the view itself. Second, the dummy view is a full member of the view hierarchy, which means that it adds overhead to every task the hierarchy performs. Worst of all, the invisible dummy view can intercept messages that are intended for other views, causing problems that are very difficult to find."
有关更多信息,请参见文档.
For more see documentation.
不建议使用它,但出于学习目的:UIViewController
具有2个虚拟框.顶部的1个属性为topLayoutGuide
,底部的另一个属性为bottomLayoutGuide
. viewController本身的左/前或右/后侧没有任何指南.这两个都是UILayoutGuide
It's deprecated for but for learning purposes: A UIViewController
has 2 dummy boxes. 1 property at the top named topLayoutGuide
and another property at the bottom named bottomLayoutGuide
. The viewController itself doesn't have any guides for its left/leading or right/trailing sides. Both of these are an instance of UILayoutGuide
如果仅限于view.topAnchor,即:
if constrained to view.topAnchor ie:
tableView.topAnchor.constraint(equalTo: view.topAnchor)
tableView 不是不是从导航栏的底部开始.请注意navigationBar后面的橙色...
tableView doesn't start from the bottom of the navigationBar. Notice the orange behind the navigationBar...
但是,如果将其限制为topLayoutGuide.bottomAnchor
,即:
However if you constrained it to topLayoutGuide.bottomAnchor
ie:
tableView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor)
然后tableView从导航栏的底部开始
then tableView starts from the bottom of the navigationBar
根据您的版式设计,您可能希望导航栏下方的内容变得模糊.
And depending on your layout design you might want your content to be blurred below the navigation bar.
当时的想法是,您可以边到边显示内容.和 它会把条子叠起来,这样您就可以得到这些漂亮的彩色 栏上的内容模糊不清
And the idea was that you would display your content edge to edge. And it would underlap the bars so that you could get these nice colorful blurs with your content through the bars
有关更多信息,请参见来自WWDC的时刻和这个问题此处.我认为解决方案并不完全相关,仅是问题中的图像.
For more see this moment from WWDC and this question here. I don't think the solutions are exactly related, just the image in the question.
safeAreaLayoutGuide
自iOS11起
Apple已弃用
topLayoutGuide
&bottomLayoutGuide
.所以 现在不再有两个虚拟框,而是有一个名为 在UIView实例上safeAreaLayoutGuide
. UIViewController不再具有任何此功能... 从 useyourloaf 复制的视觉比较:
since iOS11
Apple has deprecated
topLayoutGuide
&bottomLayoutGuide
. So instead of having two dummy boxes, you now have one dummy box namedsafeAreaLayoutGuide
on the UIView instance. UIViewController no longer has any of this... A visual comparison copied from useyourloaf:
旁注:如果使用情节提要,则将视图与topLayoutGuide或safeAreaLayoutGuide的顶部对齐将呈现相同的效果.如果您不使用情节提要(以编程方式进行),则必须在iOS11和LessThaniOS11之间跳舞,并使用2个不同版本的代码
有关safeAreaLayoutGuide
的更多信息,我高度,建议您设置
For more on safeAreaLayoutGuide
, I highly recommend that you set Apple's article on: Positioning Content Relative to the Safe Area
注意::safeAreaLayoutGuide
是UIView属性. topLayoutGuide
是UIViewController属性.
NOTE: safeAreaLayoutGuide
is a UIView property. topLayoutGuide
is a UIViewController property.
-
UIView
只有1个虚拟框.该属性名为layoutMarginsGuide
.但是与UIViewController
不同,它不在顶部或底部.它只是位于中心,在UIView
中有8个填充点/插入点(从所有4个侧面).那么这在哪里有用?:如果您不要, 't 希望将textView限制在UIView实例的边缘.这将改善阅读体验.或将按钮添加到锚点上,而不是将按钮约束到其superview的leaderAnchor上使其看起来丑陋,即,将按钮约束到leaderAnchor,然后添加8个常数点.罢工文本实际上是您要使用的readableContentGuide
位置,如果您不想将按钮或标签锚定置于其超级视图的边缘,layoutMarginsGuide
很有用
UIView
has only 1 dummy box. The property is namedlayoutMarginsGuide
. But unlikeUIViewController
it doesn't sit at the top or bottom. It just sits at the center with 8points padding/inset (from all 4 sides) into theUIView
.So where is this useful?:You would use this if you don't want your textView to be constrained to the edges of a UIView instance. This would improve the reading experience. Or instead of constraining a button to the leadingAnchor of its superview and making it look ugly, you add 8 points to the anchor...ie constraint the button to the leadingAnchor and then adding 8 constant points.The striked text, is actually where you would usereadableContentGuide
,layoutMarginsGuide
is useful if for when you don't want your button or label anchored to the edge of its superview
someButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8)
但是等等,这是一种更简单的方法.只需使用苹果推荐的保证金即可,即:
But wait there is an easier way. Just use Apple's recommended margin ie use:
someButton.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor)
Also see the example provided in documentation. A good Raywenderlich tutorial can be found here
-
与
layoutMarginGuide
略有不同.两者都是UIView的属性.有时它们是相同的,有时却是不相同的.目的是:
Is slightly different from
layoutMarginGuide
. Both are properties of UIView. Sometimes they are identical sometimes they aren't. It's purpose is:
此布局指南定义了一个易于阅读的区域,而无需 迫使用户移动其头部以跟踪线条
This layout guide defines an area that can easily be read without forcing users to move their head to track the lines
有关更多信息,请参见 WWDC的这一刻:构建自适应布局,这真棒 useyourloaf教程.
For more see this moment from WWDC: building Adaptive layout and this awesome useyourloaf tutorial.
在纵向安装的iPhone 7 Plus上,可读的内容指南相同 以视图的边距为准,但是在风景中,白色较多 文本视图两侧的空格.在横向iPad上, 空白空间显着增加.
On the iPhone 7 Plus in portrait, readable content guides are the same as the view’s margin guides, but in landscape there is more white space on either side of the text view. On the iPad in landscape, the white space is increased significantly.
边距大小取决于系统的动态类型.越大 字体,则指南将更宽.
The margin size depends on the system’s dynamic type. The larger the font, the wider the guide will be.
在下面的图像中,青色锚定到layoutMarginGuide
,而绿色锚定到readableContentGuide
:
In the image below the cyan is anchored to the layoutMarginGuide
, but the green is anchored to the readableContentGuide
:
如果要更改layoutMarginsGuide
,即将所需边距从8点更改为16点,则必须先更改layoutMargins
的值,然后再更改layoutMarginsGuide
的锚会自动更新.
UIEdgeInsets
只是您layoutMargins
的类型. layoutMargins
是UIView
类
If you want to change your layoutMarginsGuide
ie change the desired margin from 8 points to 16 points then you must change the layoutMargins
's value and then the layoutMarginsGuide
's anchors would get automatically updated.
UIEdgeInsets
is just the type of your layoutMargins
. layoutMargins
is a property name of the UIView
class
someview.layoutMargins = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)
我发现此代码☝️起作用的唯一位置是viewDidLayoutSubviews
内部.有关更多信息,请参见此处
The only place I found this code ☝️ to have its effect is inside viewDidLayoutSubviews
.For more see here
它们是基础,但没什么特别的.它们是任何UIView/UILayoutGuide中最远的边缘. UIView和UILayoutGuide实例都具有它.最终,您受约束的一切都会受到锚点的约束,而将实体锚定到的锚点只是问题.它可以是safeAreaLayoutGuide
的锚点,可以是layoutMarginGuide
的锚点,可以是topLayoutGuide
的锚点,也可以是view
的锚点. (尽管您也可以将heightAnchor锚定为50,所以在这种情况下就没有其他锚定了)
They're foundational but nothing special to it. They are the farthest edge of any UIView/UILayoutGuide. Both UIView and UILayoutGuide instances have it. EVERYTHING you constrain is eventually constrained using anchors, it's just a matter of to what entity's anchors you are anchoring it to. It could be a safeAreaLayoutGuide
's anchor, it could be a layoutMarginGuide
's anchor, it could be a topLayoutGuide
's anchor it could be a view
's anchor. (though you may also just anchor your heightAnchor to 50, so in that case there isn't another anchor)
从答案中可以找到layoutMarginsGuide
和Anchors
之间的出色视觉对比一个>.它是使用情节提要板完成的,因此更易于理解.
A great visual comparison between layoutMarginsGuide
and Anchors
can be found from this answer. It's done using storyboards so it makes it easier to understand.
重要的是要理解,这是完全不同的讨论,与其他讨论无关.它特定于UIScrollViews.有关更多信息,请参见这篇很棒的文章
While it's important to understand, is a totally different discussion and has nothing to do with the others. It's specific to UIScrollViews. For more see this great article
为了安全起见,确保所有内容都在内部中,请使用safeAreaLayoutGuide
.如果要使用系统提供的边距来更好地布局视图或填充某些内容,请使用layoutMarginGuide
,如果要使内容更易读readableContentGuide
.
To be safe and sure everything is inside your view use safeAreaLayoutGuide
. If you want to use the system provided margins to have better layout of views or have some of padding then, use layoutMarginGuide
, if you want to make things more readable readableContentGuide
.
readableContentGuide
的大小始终小于或等于layoutMarginGuide
.
layoutMarginGuide
的大小始终小于或等于safeAreaLayoutGuide
The readableContentGuide
's size is always smaller or equal to layoutMarginGuide
.
The layoutMarginGuide
's size is always smaller or equal to safeAreaLayoutGuide
layoutMargins
与CSS的填充非常相似. safeAreaLayoutGuide
与CSS边距相似.我不知道readableContentGuide
layoutMargins
is very similar to CSS's padding. safeAreaLayoutGuide
is similar to CSS margins. I don't know if there is any CSS equivalent for readableContentGuide
它们用于scrollViews,与其余答案无关.至于什么contentInset
& contentOffset
是,请参阅此日期来自WWDC 2018:UIKit:适用于各种尺寸和形状的应用程序
.视频很简单.另请参阅下面的Karthik答案.话虽如此,至关重要的是,您必须充分了解scrollView的工作原理并理解contentSize
是什么,否则会很复杂.有关contentSize
和scrollView的更多信息,请参见 Vacawama在这里的答案
They are for scrollViews, and somewhat unrelated to the rest of the answer. As for what contentInset
& contentOffset
are, please see this moment from WWDC 2018: UIKit: Apps for Every Size and Shape
. The video is very simple. Also refer to Karthik's answer below. Having that said it's vital that you fully understand how a scrollView works and understand what contentSize
is, otherwise it would be complicated. For more on contentSize
and scrollView see Vacawama's answer here
这篇关于在iOS上,页边距,边缘插图,内容插图,对齐矩形,布局页边距,锚点之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!