如何理解自动布局约束的第一项和第二项?

How to understand auto layout constraint's first item & second Item?

提问人:ximmyxiao 提问时间:1/27/2015 最后编辑:ximmyxiao 更新时间:1/27/2015 访问量:5648

问:

如果我在 xib 中使用 tableView 作为 View 的 subView。并且 tableView 完全覆盖了 View。但是在xib的attributor中,我可以看到刚才添加的两个垂直约束:第一个约束使用tableView的top作为第一项,superView的top作为第二个项,但是在第2个约束中则显示superView的底部是第一项,tableView的bottom是第二项。XIB决定使用WHO作为第一项和第二项的原因是什么。

iOS 自动布局

评论


答:

23赞 Ken Thomases 1/27/2015 #1

所有约束都表示以下形式的公式:

firstItem.firstItemAttribute == secondItem.secondItemAttribute * multiplier + constant

(关系也可以是 或 。<=>=

大多数情况下,乘数是 1,所以去掉:

firstItem.firstItemAttribute == secondItem.secondItemAttribute + constant

通常最容易用正常数来思考。所以,像这样:

view.Top == superview.Top + 20

意义。视图的顶部比超级视图的顶部低 20 磅。(在自动布局使用的坐标系中,Y 向下递增,因此添加 20 个点会给出“下方”的位置。

您可以切换项目,但是,如果您想要相同的关系,则需要否定常量:

superview.Top == view.Top + -20

-20 可能会使它更难理解。顺便说一句,Xcode 会很乐意交换这两个项目并为您否定常量。(如果乘数不是 1,数学会变得有点复杂,但仍然是可能的。

如果你只是交换项目而不否定常量,它将表达不同的关系:

superview.Top == view.Top + 20

这意味着上视图的顶部将低于视图的顶部。或者,更确切地说,视图将位于上视图的顶部上方,并且其顶部将被剪裁。

现在,另一端的约束通常用其他顺序的项来表示,因为您通常希望关系相反。也就是说,您希望视图的顶部低于上视图的顶部,但希望视图的底部高于上视图的底部。因此,仅当您按其他顺序排列项目时,常数才为正:

superview.Bottom == view.Bottom + 20

评论

0赞 gabbler 1/27/2015
很好的解释,水平间距呢?它的默认值为 -16,似乎不是自然。view.leading = superview.leading margin - 16
0赞 ximmyxiao 1/27/2015
thx ,我认为公式“firstItem.firstItemAttribute == secondItem.secondItemAttribute * 乘数 + 常量”用于根据 secondItem 的框架计算第一个项目的框架。所以这个公式不会和secondItem的帧的计算有任何关系,我说得对吗?
0赞 Ken Thomases 1/27/2015
@gabbler:水平的工作方式与垂直类似:“前导”类似于“顶部”,而“尾随”类似于“底部”(因为坐标系从“前导/顶部”增加到“尾随/底部”)。我不熟悉 iOS 和边距的东西。如果视图的“前缘”应朝向上视图的“前导”(Leading)的尾部(通常向右),则通常为 。但是,如果您表示相对于边距的相同位置,则为 。这可能是负面的。view.Leading == superview.Leading + Nview.Leading = superview.Leading margin + (N - margin width)(N - margin width)
5赞 Ken Thomases 1/27/2015
@ximmyxiao:不,你说得不对。公式是一个方程式,而不是赋值。它不是“将 firstItem.firstItemAttribute 设置为......的结果”。它是“保持这个等式为真”或“保持firstItem.firstItemAttribute等于......”。这是对称的。系统尝试查找满足所有约束的所有项的所有属性的值。从逻辑上讲,它不是从某些值开始,而是从这些值开始计算其他值。(实现可能会做类似的事情,至少是暂时的,也可能不做。我不知道。secondItem 也受到约束。
0赞 ximmyxiao 1/27/2015
@KenThomases .我还有一个问题:如果我设置了两个具有相等宽度约束的标签(labelA,labelB),并且labelA有更多的文本(意味着这个标签应该更宽),那么自动布局如何选择这两个标签将使用的宽度。(展开标签 B 或缩小标签 A)