自动布局 - 6 个视图的平均分布 [英] Autolayout - equal distribution of 6 views

查看:14
本文介绍了自动布局 - 6 个视图的平均分布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在一个视图中布置 6 个对象(按钮).但是,它们应该遵循一些限制:

  • 两个顶部按钮与父视图的垂直距离应相同 (A)
  • 两个底 - 相同(C)
  • 中间的两个应该在 superview 的中心线上有他们的中心
  • 所有按钮(E)之间的垂直距离应该相同
  • 最后但同样重要的是 - 按钮应该是方形的(所以宽度和高度应该相同)
  • A = C
  • B = D

是否有可能仅在 IB 中产生这种效果,或者我应该为约束使用一些额外的代码?

解决方案

这是一个逻辑请求,但是约束是使用视图的属性定义的,但不能相对于其他约束不定义.话虽如此,有很多方法:

  1. 布局指南: 一种不需要预先确定任何间距的方法是使用 UILayoutGuide 对象,或者,如果使用 iOS 9 之前的版本,只需使用隐藏视图,即在按钮之间具有清晰背景或 alpha 为零的视图.

    我们的想法是在您的六个按钮之间添加这些布局指南作为间隔"",并将垫片定义为彼此相同的大小,并且在垫片、超级视图和将进入垫片之间的按钮之间具有约束.布置好之后(以蓝色显示水平间隔视图,以红色显示垂直间隔视图,以便您可以看到它们):

    这些红色 UIView 对象(称为 vspacerX)的约束的等效 VFL 将是:

    <上一页>H:|[vspacer1][button1(100)][vspacer2(==vspacer1)][button2(==button1)][vspacer3(==vspacer1)]|H:|[vspacer1][button3(==button1)][vspacer2][button4(==button1)][vspacer3]|H:|[vspacer1][button5(==button1)][vspacer2][button6(==button1)][vspacer3]|

    以及对蓝色UIView对象的约束,叫做hspacerX,比如:

    <上一页>V:|[hspacer1][button1(100)][hspacer2(==hspacer1)][button3(==button1)][hspacer3(==hspacer1)][button5(==button1)][hspacer4(==hspacer1)]|V:|[hspacer1][button2(==button1)][hspacer2][button4(==button1)][hspacer3][button6(==button1)][hspacer4]|

    您不必使用 VFL 来定义这些约束,因为您定义这些约束的任何方式都可以,但它只是描述我使用的约束集合的简明格式.

    无论如何,当使用这些布局指南(或不可见的视图)呈现视图时,它会产生像这样间隔均匀的按钮:

  2. 另一种方法是拥有六个容器"视图,如下所示:

    这六个容器 UIView 对象的等效 VFL 可能如下所示:

    <上一页>H:|[容器1][容器2(==容器1)]|H:|[container3(==container1)][container4(==container1)]|H:|[container5(==container1)][container6(==container1)]|V:|[container1][container3(==container1)][container5(==container1)]|V:|[container2(==container1)][container4(==container1)][container6(==container1)]|

    然后您可以在其中添加按钮,在六个小容器中的每一个上居中一个,然后使您的容器清晰:

    这也可行,只是间距略有不同(其中边距是视图之间间距的一半,而另一种方法使边距与它们之间的间距相同.

  3. 堆栈视图: 换一种说法,在 iOS 9 中,您还可以使用 UIStackView,专为均匀间距视图而设计.在这种情况下,将两个按钮分别放在三个水平堆栈视图中,然后将这些堆栈视图放置在垂直堆栈视图中.这实现了六个大小均匀的容器视图.

    观看 WWDC 2015 视频 Cocoa Touch 的新功能.

    堆栈视图的问题在于它们可用于确保排列的子视图之间的间距均匀,它们不能确保在第一个排列视图之前或最后一个排列视图之后的间距.因此,解决这个问题的方法是,对于水平堆栈视图,包括另外两个零宽度视图(或垂直堆栈视图的零高度).然后,当您在堆栈视图上使用均匀间距时,它还会为您提供所有排列的子视图之前和之后的间距.

  4. NSLayoutAttributeCenterXmultiple: 另一种技术涉及定义 attribute:NSLayoutAttributeCenterX六个按钮的属性:NSLayoutAttributeCenterY 属性,但不要使用 constant 值,而是使用 multiplier 字段.这种技术有点简单,但并不总是能呈现出想要的效果,所以我不会描述它,除非它是你确实想要追求的东西.我已经在这里进入了 tl:dr 领域.

  5. 集合视图: 另一种方法是使用 UICollectionView,优雅地处理这种情况.它经过精心设计,可让您在网格中布局单元格.

  6. 硬编码值:为了完整起见,我注意到您可以简单地为 A、B、C 和 D 指定特定值(以及宽度和高度)约束).您甚至不必担心设置 E 约束,而只需将中间两个的垂直中心约束设置为它们的超级视图,您就可以有效地完成(因为 E 表示的间距应该是自然的结果前面的步骤,假设 A=C 和 B=D).如果您想根据设备大小和/或方向调整这些值,则可以实现 viewWillLayoutSubviews 以根据视图大小调整这些约束的常量.

I want to have 6 objects (buttons) laid out inside one view. They should, however, follow some constraints:

  • Two top buttons should have the same vertical distance from superview (A)
  • Two bottom - the same (C)
  • Two in the middle should have their centers at the superview's center line
  • The vertical distances between all buttons (E) should be the same
  • and last but not least - the buttons should be square (so the width and height should be the same)
  • A = C
  • B = D

Is it possible to have this effect just in the IB, or should I use some additional code for the constraints?

解决方案

This is a logical request, but constraints are defined using the attributes of views, but cannot not be defined in relation to other constraints. That having been said, there are a number of approaches:

  1. Layout guides: An approach which doesn't require predetermining the any spacing is to have UILayoutGuide objects or, if using iOS versions before 9, just use hidden views, i.e. views with clear background or alpha of zero, in between the buttons.

    The idea is to add these layout guides with addLayoutGuide (or add invisible views with addSubview if supporting iOS versions predating iOS 9) in between your six buttons as "spacers", and define the spacers to be the same size as each other, and with constraints between the spacers, the superview, and the buttons that will go in between the spacer. Once you lay that out (showing the horizontal spacer views in blue, vertical ones in red, just so you can see them):

    The equivalent VFL for the constraints for those red UIView objects, called vspacerX, would be:

    H:|[vspacer1][button1(100)][vspacer2(==vspacer1)][button2(==button1)][vspacer3(==vspacer1)]|
    H:|[vspacer1][button3(==button1)][vspacer2][button4(==button1)][vspacer3]|
    H:|[vspacer1][button5(==button1)][vspacer2][button6(==button1)][vspacer3]|
    

    And constraints on the blue UIView objects, called hspacerX, like:

    V:|[hspacer1][button1(100)][hspacer2(==hspacer1)][button3(==button1)][hspacer3(==hspacer1)][button5(==button1)][hspacer4(==hspacer1)]|
    V:|[hspacer1][button2(==button1)][hspacer2][button4(==button1)][hspacer3][button6(==button1)][hspacer4]|
    

    You don't have to use VFL to define these constraints, as any way you define these constraints will work, but it's just a concise format for describing the collection of constraints that I employed.

    Anyway, when the view is rendered with those layout guides (or invisible views), it yields evenly spaced buttons like so:

  2. Another approach is to have six "container" views, that would look like:

    The equivalent VFL for these six container UIView objects might look like:

    H:|[container1][container2(==container1)]|
    H:|[container3(==container1)][container4(==container1)]|
    H:|[container5(==container1)][container6(==container1)]|
    
    V:|[container1][container3(==container1)][container5(==container1)]|
    V:|[container2(==container1)][container4(==container1)][container6(==container1)]|
    

    You can then add your buttons to that, centering one on each of the six little containers and then make your containers clear:

    This works, too, but just a slightly different spacing (where the margins are half of the spacing between the views, whereas the other approach keeps the margins the same as the spacing between them.

  3. Stack view: In a permutation of the prior point, in iOS 9, you can also use UIStackView, designed precisely for evenly spacing views. In this case, put two buttons each in three horizontal stack views, and then place those stack views within a vertical stack view. This achieves six evenly sized container views.

    See WWDC 2015 video What's New in Cocoa Touch.

    The problem with stack views is that they can be used to ensure even spacing between the arranged subviews, they don't ensure spacing before the first arranged view nor after the last arranged view. So, the kludge to get around that is to, for horizontal stack view, include two more zero width views (or zero height for vertical stack views). Then when you use even spacing on the stack view, it also give you what will appear to be spacing before and after all of the arranged subviews.

  4. NSLayoutAttributeCenterX with multiple: Another technique involves defining the attribute:NSLayoutAttributeCenterX and attribute:NSLayoutAttributeCenterY attributes for your six buttons, but rather than using the constant values, use the multiplier field. This technique enjoys a little simplicity, but doesn't always render the desired effect, so I won't describe it unless it's something you definitely want to pursue. I've already entered tl:dr territory here.

  5. Collection view: Another approach is to use a UICollectionView, which handles this scenario gracefully. It's well designed to let you layout cells in a grid.

  6. Hardcoding values: For the sake of completeness, I'll note that you could simply specify specific values for A, B, C, and D (as well as the width and height constraints). You don't even have to worry about setting the E constraints, but rather just set the vertical center constraint of the middle two to their superview, and you're effectively done (because the spacing represented by E should be a natural result of the previous steps, assuming A=C and B=D). If you want to adjust these values on the basis of device size and/or orientation, you can then implement a viewWillLayoutSubviews to adjust the constants for these constraints according to the size of the view.

这篇关于自动布局 - 6 个视图的平均分布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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