Autolayout - 平均分配6个视图

ken*_*der 7 xcode interface-builder autolayout

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

在此输入图像描述

  • 两个顶部按钮应与superview(A)具有相同的垂直距离
  • 两个底部 - 相同(C)
  • 中间的两个中心应该在superview的中心线上
  • 所有按钮(E)之间的垂直距离应相同
  • 最后但并非最不重要 - 按钮应为方形(因此宽度和高度应相同)
  • A = C
  • B = D

是否有可能只在IB中产生这种效果,还是应该使用一些额外的代码来约束?

Rob*_*Rob 23

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

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

    我们的想法是在你的六个按钮之间添加这些布局指南addLayoutGuide(或者在addSubviewiOS 9之前添加不可见的视图)作为"间隔符",并将间隔符定义为彼此相同的大小,并且之间存在约束垫片,超视图和按钮将进入垫片之间.一旦你把它放在外面(用蓝色显示水平间隔视图,用红色显示垂直间隔视图,这样你就可以看到它们):

    spacer观点

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

    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:|[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)]|
    

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

    只是按钮

    这也是有效的,但只是略有不同的间距(边距是视图之间间距的一半,而另一种方法保持边距与它们之间的间距相同).

  3. 堆栈视图:在先前点的排列中,在iOS 9中,您还可以使用UIStackView,精确设计用于均匀间隔视图.在这种情况下,将两个按钮分别放在三个水平堆栈视图中,然后将这些堆栈视图放在垂直堆栈视图中.这实现了六个大小均匀的容器视图.

    请参阅WWDC 2015视频Cocoa Touch的新功能.

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

  4. NSLayoutAttributeCenterXwith multiple:另一种技术涉及为六个按钮定义attribute:NSLayoutAttributeCenterXattribute:NSLayoutAttributeCenterY属性,但不使用这些constant值,而是使用该multiplier字段.这种技术虽然有点简单,但并不总能呈现出所需的效果,所以我不会描述它,除非它是你绝对想要追求的东西.我已经进入了tl:dr领土.

  5. 集合视图:另一种方法是使用a UICollectionView,它可以优雅地处理这个场景.它设计得很好,可以让您在网格中布局单元格.

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