自动布局 - 使视角的高度相对于超级景观高度的一半

问题描述:

最近进入了自动布局,我被困在看起来像一个非常微不足道的问题的例子。我有一种观点,我想坐在屏幕的顶部,占据屏幕高度的一半。在自动布局之前简单 - 只需将其固定就位,并在超级视图调整大小时告诉它垂直扩展。自动布局 - 使视角的高度相对于超级景观高度的一半

现在,我不能为我的生活看到如何去做。下面是我得到的,当我尝试此设置:

autolayout blues

底部空间限制设置为“等于284”,当我改变对iPhone4的布局,是绝对的,绝对对我没用,因为它在屏幕底部保留284个点的空间,并将视图缩小到不再是屏幕大小的一半。而且也没有设置该约束等于任何其他视图的高度的某一部分的方式..

挣扎了一会儿后,我能想到这样做的唯一方法是要介绍的这款视图下方另一种观点认为,它们的管脚高度相等,让他们坐在上面和下面,然后设置第二个(底部)视图是隐形的......这看起来有点难看!

我失去了一些东西明显?..

+1

我不认为这是丑陋的,但一个聪明的把戏,让你想使用什么IB。我已经这样做了,当你使用正确的元素名称时,你可以清楚发生了什么。你甚至可以在不同的位置或中心有第三个元素,根据这两个子视图改变大小。 – Jelle 2013-12-19 12:36:38

从[至少] Xcode 5.1.1开始,这在IB中是可行的。虽然我花了一段时间才发现它实际上超级简单:

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

Demonstration of steps above

然后你就可以调整乘数。如果你想让超级视图的50%保留在1,因为它是按照超级中心对齐的。这也是创建视图是其他百分比过一个伟大的方式(如超图的25%)

Demonstration of second step above

+0

不错:)我认为这篇文章应该被标记为接受答案:) iOS开发人员经常喜欢Interface Builder解决方案而不是类似代码的解决方案 – hqt 2014-09-13 19:14:05

+0

@hqt,谢谢。我认为,当接受的答案写成这种方法是不可用的。有时候提问者不会重新提出旧问题或者关心改变被接受的答案。但最终我只是在这里帮忙,很高兴它! – Firo 2014-09-13 19:46:42

+2

我有点困惑。我尝试过,但它只是将视图集中到超级视图中,而不是调整视图的高度。 – Dean 2014-10-31 14:57:59

后多一点的时间,我想出了以下内容。

我注意到它作为一个答案,但它不是非常令人满意,因为它假设在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,以避免关于中断约束的一堆运行时消息。因此,如果任何人都可以展示如何在界面生成器中做到这一点,那会更好地回答我的问题,否则我认为这是一样好(现在)?

+3

我认为这是现在的状况。如果Apple允许我们访问IB中的乘数值,那将是很好的,因此可以将其设置为常数。 – rdelmar 2013-02-18 16:48:41

+3

对于任何正在查看此答案的人,Xcode 5.1现在允许您通过Interface Builder设置乘数。我现在可以通过IB配置其超级视图高度的一半。 – 2014-04-05 14:18:05

我还有另外一种可能性,如果你有两个视图应该具有相同的高度:只需将view2的高度设置为view1的高度(这里的技巧不是明确设置view1的高度)。

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

没有意识到你可以参考宽度/高度这样的其他意见。如果您已经使用了视觉格式语言,这是最干净的答案。 – loeschg 2014-09-05 14:47:18

+0

@brainray示例也在[developer.apple.com here](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample)中进行了解释。html#// apple_ref/doc/uid/TP40010853-CH5-SW7) – 2015-03-12 23:09:20

故事板解决方案,你可以设置任何意见之间的精确率:

Set height equality constraint

现在:

Edit constraint's multiplier

利润!

Result

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

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

+0

第2步似乎不适合我。除了切换“约束到边距”外,我无法在面板中选择任何内容。我试图将UITableViewCell中的UIImageView的宽度设置为内容视图的50%。 – DrMickeyLauer 2014-12-29 17:15:39

+1

更新:很明显,界面生成器不允许内容视图成为任何自动布局约束的显式目标。我必须插入一个虚拟子视图作为内容视图的子项才能完成此项工作。 – DrMickeyLauer 2014-12-29 19:54:06

+1

它适合我。您需要选择列表中的两个视图,而不是构建器屏幕。对于百分比,将较小视图与较大视图分开,以获得乘数值示例较小视图25,较大视图135-25/135 = 0.185。设置这个乘数值来得到x1和x2 = 25的视图,但是用更大的6和6加上等等。 – latenitecoder 2015-01-29 22:22:56

比方法比Fyodor Volchyok的答案稍简单,也比方法更直接。 - 按住控制按钮并点击子视图。 - 只需按住命令按钮,将光标拖到超级视图,然后单击超级视图。 - 选择“长宽比”。

enter image description here

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

- 确保为这两个项目选择了“高度”。 enter image description here

- 然后将“乘数”更改为0.5半屏或任何你想要的超视图分数。 enter image description here

+0

简单快捷的方法!谢了哥们 – 2017-05-10 01:51:27

丈量的回答斯威夫特版本:

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) 


}