自动布局-视图高度相对于半视图高度

最近一直在研究自动布局,我被一个看起来非常琐碎的问题例子所困扰。我有一个视图,我想坐在屏幕的顶部,占据屏幕高度的一半。简单的自动布局之前-只要钉在适当的地方,并告诉它,以垂直展开时,总览调整大小。

现在,我无论如何也不知道该怎么做。当我试图安排这个时,我得到了这样的结果:

autolayout blues

底部的空间限制被设置为“等于284”,当我切换到 iPhone4的布局时,这对我来说是绝对没有用的,因为它在屏幕底部保留了284个点的空间,并将视图缩小到不再是屏幕的一半大小。而且没有办法将这个约束设置为等于任何其他视图高度的某个分数。.

在挣扎了一段时间之后,我能想到的唯一方法就是在这个视图之下引入另一个视图,平均地固定他们的高度,让他们坐在彼此的上方和下方,然后设置第二个(底部)视图是不可见的。.看起来有点丑!

我是不是漏掉了什么明显的东西。

94410 次浏览

再过一段时间,我想出了以下几点。

我注意到这是一个答案,但它并不是很令人满意,因为它假设你不能在 Interface Builder 中实际做到这一点,但是正确的约束可以在代码中添加如下:

- (void) viewWillAppear:(BOOL)animated
{


NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:upperview
attribute:NSLayoutAttributeHeight
relatedBy:0
toItem:self.view
attribute:NSLayoutAttributeHeight
multiplier:.5
constant:0];
[self.view addConstraint:constraint];


}

基本上,它对 self. view 的高度设置了一个0.5的乘数,作用于 upperview。 我必须将 IB 中底部垂直空间约束的优先级设置为低于1000,以避免一堆关于打破约束的运行时消息。

因此,如果有人能够在 Interface Builder 中展示如何做到这一点,那么最好能够回答我的问题,否则我想这已经是(目前)最好的了?

在代码中还有另一种可能性,如果你有两个视图,它们应该具有相同的高度: 只需将 view2的高度设置为 view1的高度(这里的诀窍是不显式地设置 view1的高度)。

    [self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:[topLayoutGuide]-0-[_view1]-0-[_view2(==_view1)]-0-[bottomLayoutGuide]"
options:0
metrics:nil
views:viewsDict]];

现在在 IB 中[至少] Xcode 5.1.1中可以做到这一点。虽然我花了一些时间才弄明白这其实非常简单:

首先创建一个基本的顶部对齐约束(您还需要设置底部、左边和右边的约束,就像平常一样) 。然后选择约束并导航到 属性检查器:

Demonstration of steps above

然后你可以调整乘数。如果你想它50% 的超级视图离开它在 1,因为它是对齐每超级的中心。这也是一个创建其他百分比视图的好方法(比如25% 的超级视图)

Demonstration of second step above

故事板解决方案,您可以设置任何视图之间的精确比例:

Set height equality constraint

现在:

Edit constraint's multiplier

利润! ! !

Result

另请注意,此方法适用于不同嵌套级别的视图,并且(显然)适用于宽度

P.P.S 有时候,“反向第一和第二项”的约束或设置反向乘数(例如2而不是0.5)可能是有帮助的(但是如果你不理解视图之间是如何相互关联的,这些方法是没有帮助的)。

比 Fyodor Volchyok 的回答更简单,更直接。 按住控制按钮,点击视图。 - 仍然按住命令按钮,将光标拖动到“超级视图”,然后单击“超级视图”。 - 选择「长宽比」。

enter image description here

- 然后点击大小检查器。 - 然后双击约束。 enter image description here

- 确保两个项目都选择了“身高”。 enter image description here

然后把半个屏幕的“乘法器”改成0.5或者你想要的超级视图的任何部分。 enter image description here

梅特迅速回答道:

    override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.






upperView.translatesAutoresizingMaskIntoConstraints = false




var constraint = NSLayoutConstraint(item: upperView,
attribute: NSLayoutAttribute.top,
relatedBy: NSLayoutRelation.equal,
toItem: self.view,
attribute: NSLayoutAttribute.top,
multiplier: 1,
constant: 0)


self.view.addConstraint(constraint)




constraint = NSLayoutConstraint(item: upperView,
attribute: NSLayoutAttribute.height,
relatedBy: NSLayoutRelation.equal,
toItem: self.view,
attribute: NSLayoutAttribute.height,
multiplier: 0.5,
constant: 0)


self.view.addConstraint(constraint)




constraint = NSLayoutConstraint(item: upperView,
attribute: NSLayoutAttribute.leading,
relatedBy: NSLayoutRelation.equal,
toItem: self.view,
attribute: NSLayoutAttribute.leading,
multiplier: 1,
constant: 0)


self.view.addConstraint(constraint)




constraint = NSLayoutConstraint(item: upperView,
attribute: NSLayoutAttribute.trailing,
relatedBy: NSLayoutRelation.equal,
toItem: self.view,
attribute: NSLayoutAttribute.trailing,
multiplier: 1,
constant: 0)


self.view.addConstraint(constraint)




}