Ios7 自动布局中的弹簧:在Xcode 5中均匀分布视图(带约束)
我了解在Interface Builder中对齐、调整大小和分布视图的旧Struts和Springs方法。然而,我似乎不知道如何使用Xcode 5的自动布局来均匀分布视图。有一种方法可以使用Xcode 4实现,但该选项已经不存在了 我有7个垂直排列的按钮。在3.5英寸的布局上,它看起来很棒。当我在4英寸的布局中预览屏幕时,所有的按钮都被紧紧地挤在一起,最后一个按钮下面有很大的空间 我希望它们保持相同的高度,但我希望它们之间的空间能够弯曲,这样它们就可以在屏幕上分散开来 我已经能够得到按钮的高度来伸缩和填充空间,但这不是我想要的行为。我想学习如何使用自动布局来取代我以前的Springs行为,但我似乎找不到通过Interface Builder实现这一点的方法 我同意顶部按钮与顶部边缘的距离是固定的,或者与顶部边缘的距离是成比例的,底部按钮和底部边缘也是如此。这些对我来说不太重要,我对它们都很在行Ios7 自动布局中的弹簧:在Xcode 5中均匀分布视图(带约束),ios7,interface-builder,constraints,xcode5,autolayout,Ios7,Interface Builder,Constraints,Xcode5,Autolayout,我了解在Interface Builder中对齐、调整大小和分布视图的旧Struts和Springs方法。然而,我似乎不知道如何使用Xcode 5的自动布局来均匀分布视图。有一种方法可以使用Xcode 4实现,但该选项已经不存在了 我有7个垂直排列的按钮。在3.5英寸的布局上,它看起来很棒。当我在4英寸的布局中预览屏幕时,所有的按钮都被紧紧地挤在一起,最后一个按钮下面有很大的空间 我希望它们保持相同的高度,但我希望它们之间的空间能够弯曲,这样它们就可以在屏幕上分散开来 我已经能够得到按钮的高度
但我确实需要弄清楚如何在视图中的每个项目之间均匀分配额外的空间。编辑注意,在iOS 9中,这种技术将变得不必要,因为UIStackView将自动执行分配。我将补充说明这是如何工作的 如何使用自动布局执行均匀分布 仅在Interface Builder中执行此操作的最简单方法(而不是在代码中构造约束)是使用“间隔”视图:
例如,如果我们有一个(可能是看不见的)超视图,其高度作为一个边界来指示四个按钮的最大垂直分布,我们可以用
常数0
将它们的顶部固定到该超视图的垂直中心,但乘数为0.000001
,0.66666
,1.33333
和2.0
(如果我们有四个按钮);现在,按钮将保持垂直分布,即使superview根据屏幕高度或其他因素改变大小。[在Xcode 5.1中,可以在Interface Builder中进行设置,但在早期版本的Xcode中不可能进行设置。]在iOS 9/Xcode 7中,这个问题在IB中可以轻松解决。只需选择按钮(或任何您想要垂直分布的按钮),然后选择编辑器>嵌入>堆栈视图。然后,只需配置堆栈视图:
- 提供用于定位和调整堆栈视图本身大小的约束。例如,将堆栈视图的四条边固定到其superview的四条边上
- 设置堆栈视图的属性。在这种情况下,我们需要垂直轴、填充对齐、等间距分布
就这些!但是,您可能会好奇这是如何工作的,因为仍然可以在代码中手动执行相同的操作。堆栈视图不是通过插入间隔视图,而是通过插入间隔导轨来执行分布。导向(UILayoutGuide)是一个轻量级对象,其行为类似于布局约束中的视图,但不是视图,因此不必使其不可见,也不承担视图的任何开销
为了举例说明,我将在代码中说明堆栈视图的作用。假设我们有四个垂直分布的视图。我们为它们分配除分布以外的所有约束:
- 它们都有绝对高度限制
- 其左侧固定在超级视图的左侧,右侧固定在超级视图的右侧
- 顶部视图的顶部固定到超级视图的顶部,底部视图的底部固定到超级视图的底部
现在,假设我们将这四个视图引用为视图
,一个数组。然后:
let guides = [UILayoutGuide(), UILayoutGuide(), UILayoutGuide()]
for guide in guides {
self.view.addLayoutGuide(guide)
}
NSLayoutConstraint.activateConstraints([
// guide heights are equal
guides[1].heightAnchor.constraintEqualToAnchor(guides[0].heightAnchor),
guides[2].heightAnchor.constraintEqualToAnchor(guides[0].heightAnchor),
// guide widths are arbitrary, let's say 10
guides[0].widthAnchor.constraintEqualToConstant(10),
guides[1].widthAnchor.constraintEqualToConstant(10),
guides[2].widthAnchor.constraintEqualToConstant(10),
// guide left is arbitrary, let's say superview margin
guides[0].leftAnchor.constraintEqualToAnchor(self.view.leftAnchor),
guides[1].leftAnchor.constraintEqualToAnchor(self.view.leftAnchor),
guides[2].leftAnchor.constraintEqualToAnchor(self.view.leftAnchor),
// bottom of each view is top of following guide
views[0].bottomAnchor.constraintEqualToAnchor(guides[0].topAnchor),
views[1].bottomAnchor.constraintEqualToAnchor(guides[1].topAnchor),
views[2].bottomAnchor.constraintEqualToAnchor(guides[2].topAnchor),
// top of each view is bottom of preceding guide
views[1].topAnchor.constraintEqualToAnchor(guides[0].bottomAnchor),
views[2].topAnchor.constraintEqualToAnchor(guides[1].bottomAnchor),
views[3].topAnchor.constraintEqualToAnchor(guides[2].bottomAnchor)
])
(显然,我可以使用循环使代码更简洁明了,但为了清晰起见,我特意展开了循环,以便您可以看到模式和技术。)实际上,如果您真的愿意,可以继续使用弹簧和支柱。您的故事板可以关闭自动布局。或者,如果您想同时使用自动布局和弹簧撑杆,请使用包含按钮的superview创建一个nib(.xib文件),将nib设置为不使用自动l