>两个顶部按钮应与superview(A)具有相同的垂直距离
>两个底部 – 相同(C)
>中间的两个中心应该在superview的中心线上
>所有按钮(E)之间的垂直距离应相同
>最后但并非最不重要 – 按钮应为方形(因此宽度和高度应相同)
> A = C.
> B = D.
解决方法
>布局指南:不需要预先确定任何间距的方法是使用UILayoutGuide对象,或者如果在9之前使用iOS版本,则只需在按钮之间使用隐藏视图,即背景清晰或零度为α的视图.
我们的想法是使用addLayoutGuide添加这些布局指南(或者如果在iOS 9之前支持iOS版本,则使用addSubview添加不可见的视图)作为“间隔符”在六个按钮之间,并将间隔符定义为彼此相同的大小,并使用间隔物,超视图和将在间隔物之间进入的按钮之间的约束.一旦你把它放在外面(用蓝色显示水平间隔视图,用红色显示垂直间隔视图,这样你就可以看到它们):
对于那些名为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]|
蓝色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来定义这些约束,因为您定义这些约束的任何方式都可以使用,但它只是用于描述我使用的约束集合的简明格式.
无论如何,当使用那些布局指南(或不可见的视图)渲染视图时,它会产生均匀间隔的按钮,如下所示:
>另一种方法是有六个“容器”视图,看起来像:
这六个容器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视频What’s New in Cocoa Touch.
堆栈视图的问题在于它们可用于确保排列的子视图之间的均匀间隔,它们不能确保在第一个排列的视图之前或最后排列的视图之后的间距.因此,对于水平堆栈视图,要解决的问题是,包括两个零宽度视图(或垂直堆栈视图的零高度).然后,当您在堆栈视图上使用均匀间距时,它还会为您提供在所有已排列的子视图之前和之后显示间距的内容.
> NSLayoutAttributeCenterX with multiple:另一种技术涉及定义属性:NSLayoutAttributeCenterX和属性:六个按钮的NSLayoutAttributeCenterY属性,但不使用常量值,而是使用乘数字段.这种技术虽然有点简单,但并不总能呈现出所需的效果,所以我不会描述它,除非它是你绝对想要追求的东西.我已经进入了tl:dr领土.
>集合视图:另一种方法是使用UICollectionView
,它可以优雅地处理这个场景.它设计精良,可让您在网格中布局单元格.>硬编码值:为了完整起见,我会注意到你可以简单地指定A,B,C和D的特定值(以及宽度和高度约束).您甚至不必担心设置E约束,而只需将中间两个的垂直中心约束设置为它们的超视图,并且您已经有效地完成了(因为E表示的间距应该是自然的结果前面的步骤,假设A = C且B = D).如果要根据设备大小和/或方向调整这些值,则可以实现viewWillLayoutSubviews,以根据视图的大小调整这些约束的常量.