在iOS上,页边距,边缘插图,内容插图,对齐矩形,布局页边距,锚点​​之间有什么区别? [英] On iOS, what are the differences between margins, edge insets, content insets, alignment rects, layout margins, anchors...?

查看:105
本文介绍了在iOS上,页边距,边缘插图,内容插图,对齐矩形,布局页边距,锚点​​之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于布局,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:

  1. 实例化一个新的布局指南.
  2. 通过调用视图的addLayoutGuide(_:)方法将布局指南添加到视图.
  3. 使用自动布局"定义布局指南的位置和大小. 您可以使用这些指南来定义布局中元素之间的空间.以下示例显示了用于在一系列视图之间定义相等间距的布局指南.
  1. Instantiate a new layout guide.
  2. Add the layout guide to a view by calling the view’s addLayoutGuide(_:) method.
  3. 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.

三个有趣的注释:

  1. 如果您使用的是视图调试层次结构",那么您会看到UILayoutGuide
  2. 的更多实例
  3. 就像UIView一样,UILayoutGuide 实例具有所有种锚点
  4. 关于为什么不只创建虚拟UIView并完成创建UILayoutGuides的原因:将虚拟视图添加到视图层次结构会带来许多成本.首先,创建和维护视图本身存在成本.其次,虚拟视图是视图层次结构的完整成员,这意味着它为该层次结构执行的每个任务增加了开销,最重要的是,不可见的虚拟视图会拦截旨在发送给其他视图的消息,从而导致很难解决的问题找到."
  1. If you are using the 'view debug hierarchy' then you would be seeing more instances of UILayoutGuide
  2. Just like a UIView, a UILayoutGuide instance has all kinds of anchors
  3. 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 named safeAreaLayoutGuide 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 named layoutMarginsGuide . But unlike UIViewController it doesn't sit at the top or bottom. It just sits at the center with 8points padding/inset (from all 4 sides) into the UIView.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 use readableContentGuide, 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)

另请参阅提供的示例 文档. 可以找到一个很好的Raywenderlich教程 此处

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.

来自 RayWenderlich

在下面的图像中,青色锚定到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类型. layoutMarginsUIView

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)

答案中可以找到layoutMarginsGuideAnchors之间的出色视觉对比.它是使用情节提要板完成的,因此更易于理解.

A great visual comparison between layoutMarginsGuide and Anchorscan 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆