使用NSLayoutAttributeCenterX
属性时,乘数为1会产生与引用视图匹配的中心。增加值会将其向左移动,向0移动会将其向右移动。
通过使用2.5,1和0.625的乘数,我已经能够通过试验和错误(在超视图上均匀分布3个视图)大致获得我想要的结果。在弄乱的时候,我发现200在被引用视图的左边缘居中(也增加了比不移动视图更多),而0.5在右边缘居中(朝向0减少会进一步移动视图)左)。
以下是我的问题:
答案 0 :(得分:10)
确定当乘数不是1.0时中心约束意味着什么是棘手的。我在Xcode 6中做了一些实验,这是我的结论。
相关约束的格式为A.center.x = B.center.x * m + c
,其中A
和B
是所涉及的观点,m
是约束的乘数,{c
1}}是约束的常量。
假设B' center.x
由其他一些约束修正。然后我相信autolayout就像使用这个算法一样:
找到A和B最近的共同祖先视图。称这个共同的祖先G。
让G坐标系中的bxg = B.x.center。您可以在代码中将此计算为CGFloat bxg = [G convertPoint:B.center fromView:B.superview].x
。
计算axg = A在G坐标系中所需的x中心。 CGFloat axg = bxg * m + c
。
将axg转换为A.superview
的坐标系,并将其存储为A.center.x
。
好的,所以尽管如此,我们如何使用中心约束来实现“均匀间隔视图”的目标?我们没有。
这就是问题所在。假设您的所有三个子视图具有相同的宽度,w。 (如果宽度不同,问题就更难了。)让我们说容器视图的宽度为W.有四个边距(最左边的子视图左边一个,左边的子视图和中间的子视图一边) ,中间子视图和右子视图之间,右子视图右侧之一。)
边距的宽度应该是(W - 3 w)/ 4.然后我们想以某种方式将其插入另一个约束。你想使用中心约束,但为了简单起见,我们考虑最左边视图L的左边约束。我们希望约束为L.left =(W - 3 w)/ 4.这个约束对于自动布局来说,直接处理太复杂了。 Autolayout约束只能涉及两个视图属性,但这涉及三个。
解决方案是引入间隔视图。让我们从三个期望的子视图开始:
我已经将这三个子视图中的每一个限制为80x80并垂直居中。
现在我将添加四个间隔视图,以灰色显示:
我限制了每个垫片的高度和垂直中心,但我不约束它们的宽度。我接下来要做的是约束所有的间隔物具有相同的宽度:
然后我将每个垫片的前沿和后沿固定到最近的邻居,手动将常数设置为零。这是我如何做第一个垫片:
我对其他三个垫片做同样的事情。我在这里没有表现出来。
当我选择视图控制器并要求Xcode更新所有帧时,我得到均匀间隔的视图:
由于我实际上并不希望在运行时看到垫片,我会选择它们并将它们设置为隐藏。 隐藏的视图仍然参与布局。
现在,如果子视图的宽度不同,该怎么办?让我们改变蓝色子视图的宽度:
自动布局更新帧,使间隔符的宽度保持相等。
答案 1 :(得分:0)
我发现如果你将视图与超视图中心X对齐(我相信Y轴也是如此)那么你可以用预期的视角计算乘数系数:
Coeff = superview.width / view.center.X * 0.5
即你有宽度= 600的超视图,你需要放置一个视图,其中心位于超视宽度的0.25,然后视图中心= 150
Coeff = 600 / 150 * 0.5 = 2
如果您需要对称视图,那么
Coeff = 600 / 450 *0.5 = 0.666
因此,如果您知道视图中心(CoV)为0.25,则公式为:
Coeff = 1 / CoV * 0.5