自动布局-使视图高度相对于一半超级视图高度


136

最近一直在使用自动布局,而我一直停留在一个看似微不足道的问题示例上。我有一个视图,我想坐在屏幕顶部,占据屏幕高度的一半。自动布局之前很简单-只需固定就位,并在调整超级视图大小时告诉它垂直扩展即可。

现在,我一辈子都看不到该怎么做。这是我尝试进行设置时得到的:

自动布局蓝调

底部空间约束设置为“等于284”,当我更改为iPhone4布局时,这对我来说绝对是绝对没有用的,因为它在屏幕底部保留284个点的空间,并将视图缩小到不再是屏幕的一半。屏幕尺寸。而且无法将约束设置为等于其他任何视图高度的一部分。

经过一段时间的努力,我唯一想到的方法是在该视图下引入另一个视图,将它们的高度相等地钉住,让它们彼此上下放置,然后将第二个(底部)视图设置为不可见..这看起来有点丑!

我是否缺少明显的东西?


1
我认为这并不丑陋,但是使用IB可以轻松获得所需的技巧。我已经做到了,当您使用适当的元素名称时,您可以弄清楚发生了什么。您甚至可以使第三个元素位于不同的位置或中心,从而根据这两个子视图更改大小。
耶尔(Jelle)2013年

Answers:


167

从[至少] Xcode 5.1.1起,现在在IB中是可能的。尽管我花了一些时间弄清楚它实际上非常简单:

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

上面的步骤演示

然后,您可以调整乘数。如果您想要它,则将其50%的超级视图保留在1,因为它是根据超级中心对齐的。这也是创建其他百分比视图的好方法(例如超级视图的25%)

上面第二步的演示


不错:)我认为这篇文章应该标记为已接受答案:) iOS开发人员通常更喜欢Interface Builder解决方案而不是类似代码的解决方案
hqt 2014年

@hqt,谢谢。我认为当编写接受的答案时,此方法不可用。有时,提问者不重访旧问题或关心更改接受的答案。但最终我只是在这里为您提供帮助,很高兴做到了!
费罗2014年

3
我有点困惑。我试过了,但它只是将视图居中放置在超级视图上,它不会调整视图的高度。
教务长

@Dean,你需要确保的是,First ItemView.Top不是View.Center Y。否则,是的,它将居中。您还需要确保正确设置其他约束以处理视图的其他边缘。
费罗,2014年

1
View.Top等于Superview.Center Y乘数1不会给您高度。这个答案是不完整的。您所要做的就是思考您在说什么,您会发现它使您在中心处划了一条线!我将编辑此答案以明确您正在谈论的其他约束。
smileBot 2015年

184

情节提要解决方案,您可以在其中设置任意视图之间的精确比例:

设置高度相等约束

现在:

编辑约束的乘数

利润!!!

结果

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

PPS有时可能会“逆转约束的第一项和第二项”或设置反向乘数(例如2而不是0.5)(但是如果您不了解视图之间的关系,那么这些方法将无济于事)。


1
第2步似乎不适用于我。除了切换“约束到边距”外,我无法在面板中选择其他任何内容。我正在尝试将UITableViewCell中的UIImageView的宽度设置为内容视图的50%。
DrMickeyLauer 2014年

2
更新:显然,界面构建器不允许内容视图成为任何自动布局约束的明确目标。我必须插入一个虚拟的子视图作为内容视图的子视图,以完成此工作。
DrMickeyLauer 2014年

1
这个对我有用。您需要选择列表中的两个视图而不是构建器屏幕。对于百分比,将较小的视图除以较大的视图可得到乘数值示例较小的视图25,较大的视图135-25/135 = 0.185。将此值设置为乘数,可得出x1和x2 = 25的视图,但放大比例为6和6等等,等等
–latenitecoder

1
这对我
有用

这应该是公认的答案。首先,我尝试接受的答案。它没有用,然后我向下滚动,看到了这个答案,它就起作用了。谢谢!
米希尔·奥扎

31

再过一段时间后,我提出了以下建议。

我注意到这是一个答案,但它并不令人满意,因为它假定您实际上不能在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中执行此操作,那将更好地回答我的问题,否则我想这(现在)就可以了。


3
我认为这和现在一样好。如果Apple允许我们访问IB中的乘数,那将是很好的,因此可以设置常数。
rdelmar

3
对于任何正在寻找此答案的人,Xcode 5.1现在都允许您通过Interface Builder设置乘数。现在,我可以通过IB将视图配置为其超级视图高度的一半。
Mark Krenek

9

比Fyodor Volchyok的答案要简单,直接得多。-按住控制按钮,然后单击子视图。-仍然按住命令按钮,将光标拖动到超级视图,然后单击超级视图。-选择“长宽比”。

在此处输入图片说明

-然后单击“大小检查器”。-然后双击约束。 在此处输入图片说明

-确保两个项目均选择“高度”。 在此处输入图片说明

-然后将“乘数”(Multiplier)更改为0.5,以显示一半的屏幕或所需的超级视图比例。 在此处输入图片说明


简单快捷的方法!感谢队友
阿卜杜拉·赛义德

7

如果您有2个视图都应具有相同的高度,那么在代码中还有另一种可能性:只需将view2的高度设置为view1的高度(此处的技巧不是明确地设置view1的高度)。

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

没意识到您可以像这样参考其他视图的宽度/高度。如果您已经使用视觉格式语言,这是IMO的最干净的答案。
loeschg 2014年


0

Swift版本的Mete的答案:

    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)


}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.