我想在一个视图中放置6个对象(按钮),但是它们应该遵循一些限制:
- 两个顶部按钮应该与父视图(
A
)有相同的垂直距离 - 两个底部按钮应该有相同的垂直距离 (
C
) - 中间的两个按钮应该在父视图的中心线上
- 所有按钮之间的垂直距离(
E
)应该相同 - 最后但并非最不重要的是-按钮应该为正方形(因此宽度和高度应该相同)
A
=C
B
=D
是否可以仅使用IB实现这种效果,还是需要使用额外的代码来添加约束?
我想在一个视图中放置6个对象(按钮),但是它们应该遵循一些限制:
A
)有相同的垂直距离C
)E
)应该相同A
=C
B
=D
是否可以仅使用IB实现这种效果,还是需要使用额外的代码来添加约束?
这是一个合理的请求,但是约束使用视图的属性来定义,不能与其他约束相关联。话虽如此,有几种方法:
布局指南: 一种不需要预先确定任何间距的方法是使用 UILayoutGuide
对象或者在 iOS 9 之前使用隐藏的视图,即具有清晰背景或透明度为零的视图,在按钮之间。
添加这些布局指南和定义“间隔”视图大小相同并且具有在间隔中,父视图和将放在空隙中的按钮之间的约束,最终展示水平和垂直间隔视图:
对于那些被称为 vspacerX
的红色 UIView
对象的约束等效的 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]|
而对于被称为 hspacerX
的蓝色 UIView
对象的约束,则如下所示:
V:|[hspacer1][button1(100)][hspacer2(==hspacer1)][button3(==button1)][hspacer3(==hspacer1)][button5(==button1)][hspacer4(==hspacer1)]|
你不必使用VFL定义这些约束,因为任何定义这些约束的方式都可以,但这只是一种简洁的格式,用于描述我采用的约束集合。
无论如何,当使用这些布局指南(或不可见视图)渲染视图时,它会产生均匀间隔的按钮,如下所示:
另一种方法是使用六个“容器”视图,看起来像这样:
这六个UIView
对象的等效VFL可能如下所示:
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)]|
然后您可以将按钮添加到其中,使每个小容器中心对齐,然后使容器变为透明:
这也起作用,但略有不同的间距(其中边距是视图之间间距的一半,而另一种方法保持边距与它们之间的间距相同)。
堆栈视图: 在 iOS 9 中,您可以使用专门设计用于平均分配视图的UIStackView
。在这种情况下,将每个放置两个按钮水平排列到三个堆栈视图中,然后将这些堆栈视图放置在一个垂直堆栈视图中。这样就可以实现六个大小相同的容器视图。
请参阅WWDC 2015视频Cocoa Touch 的新功能。
堆栈视图的问题在于,它们可用于确保排列的子视图之间的间距均匀,但不会确保第一个排列的视图之前和最后一个排列的视图之后的间距。因此,解决这个问题的方法是,在水平堆栈视图中包括两个更多的零宽度视图(或垂直堆栈视图的零高度)。然后,当您在堆栈视图上使用均匀间距时,它还会为您提供所有排列的子视图之前和之后似乎是间距的效果。
使用NSLayoutAttributeCenterX
和NSLayoutAttributeCenterY
属性的multiple
: 另一种技术涉及为六个按钮定义attribute:NSLayoutAttributeCenterX
和attribute:NSLayoutAttributeCenterY
属性,但不是使用constant
值来使用multiplier
字段。这种技术更简单,但并不总是呈现所需的效果,因此,除非您确定要追求这种技术,否则我不会描述它。我已经进入tl:dr领域了。
集合视图: 另一种方法是使用UICollectionView
,它可以优雅地处理这种情况,它很好地设计让您以网格方式布局单元格。
硬编码数值:为了完整起见,我会指出你可以简单地指定 A、B、C 和 D 的特定值(以及宽度和高度约束)。你甚至不必担心设置 E 约束,只需将中间两个视图的垂直中心约束设置为其 superview,你就完成了 (因为假设 A=C 和 B=D,E 表示的间距应该是前面步骤的自然结果)。如果你想根据设备大小和/或方向调整这些值,那么可以实现 viewWillLayoutSubviews
来根据视图大小调整这些约束的常量。