【问题标题】:In autolayout, how can I have view take up half of the screen, regardless of orientation?在自动布局中,无论方向如何,如何让视图占据屏幕的一半?
【发布时间】:2015-01-09 21:18:32
【问题描述】:

在纵向模式下,我在左侧有一个 tableview,在右侧有一个 webview。他们都占据了屏幕的一半。我启用了自动布局。

但是当我将屏幕旋转到横向模式时,tableview 的宽度占用不到屏幕大小的一半,而 webview 最终占用了更多,而不是它们被平均分割。

为什么会这样?无论屏幕方向如何,如何让视图仅占屏幕宽度的一半?

【问题讨论】:

标签: ios objective-c autolayout


【解决方案1】:

答案的前半部分解决了我们希望在视图 A(蓝色)和视图 B(红色)之间平均分割视图的情况。后半部分将解决我们希望视图 A 占据屏幕一半但视图 B 不存在的情况。

第 1 步:

如图所示设置 blue 的自动布局约束。上、左、下 0 到 superview。红色视图的 0 右侧。

第 2 步:

为红色视图设置相同但镜像的约束。

如果您正确完成了前两个步骤,您应该会遇到一些自动布局错误和警告:

我们还需要一个约束来修复这些错误/警告并获得我们需要的东西。

第 3 步:

按住控件,单击并从一个视图拖动到另一个视图,然后选择“等宽”。现在我们的视图将始终保持相同的宽度。我们所有的自动布局警告和错误都会消失,无论方向或设备如何,我们的视图都将始终是屏幕的一半。

要使用 VFL 在代码中添加这些约束,我们需要以下约束:

@"H:|[blueView(==redView)][redView]|"
@"V:|[blueView]|"
@"V:|[redView]|"

现在,假设我们希望单个视图占据屏幕的一半,但我们没有另一半的视图。我们仍然可以使用自动布局来做到这一点,但它的设置略有不同。在这个例子中,我们的视图是蓝色的,它的父视图是绿色的。

第 1 步:

这与上面的步骤 1 类似,只是我们不添加右侧约束(如果我们希望视图占据不同的一半,这显然会有所不同)。

第 2 步:

像以前一样,我们要分配“等宽”约束。在这种情况下,从我们的视图到父视图。同样,按住控件并单击从一个拖动到另一个。

此时,我们有一个自动布局警告。自动布局希望我们的框架匹配其父级的宽度。单击警告并选择“更新约束”将输入硬编码值。我们不希望这样。

第 3 步:

选择视图并转到其尺寸检查器。在这里,我们将能够编辑约束。

单击“等于:”约束旁边的“编辑”。我们需要更改乘数值。

我们需要将乘数值改为 2。

约束现在更改为“Proportional Width to:”,我们所有的自动布局警告和错误都消失了。现在我们的视图将始终占据超级视图的一半。

要在代码中添加这些约束,我们可以使用 VFL 添加一些:

@"H:|[blueView]"
@"V:|[blueView]|"

但不能用 VFL 添加比例宽度约束。我们必须这样添加它:

NSLayoutConstraint *constraint =
    [NSLayoutConstraint constraintWithItem:blueView
                                 attribute:NSLayoutAttributeWidth 
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superView
                                 attribute:NSLayoutAttributeWidth
                                multiplier:2.0
                                  constant:0.0]; 

【讨论】:

  • 惊人的答案,我喜欢你付出的努力。既然我知道了相等的宽度,您知道如何以编程方式设置它吗?这行得通吗? @"[leftView][rightView][leftView(==rightView)]"
  • 使用 VFL 设置等宽约束就像 @"[leftView(==rightView)]" 一样简单。但是您还需要其他约束。所以你想要:@"|[leftView(==rightView)][rightView]|"(你仍然需要垂直约束)
  • (还记得你可以更改接受的答案。)
  • 这给了我两个视图的相同宽度,但彼此堆叠,而不是像原来的那样并排。这就是你所说的垂直约束吗?
  • 在该字符串前面放一个H:。因此,您要创建这些约束:@"H:|[leftView(==rightView)][rightView]|" 用于水平,而对于您要创建的垂直:@"V:|[leftView]|"@"V:|[rightView]|"
【解决方案2】:

XIBStoryboard 中创建UIView

  1. 设置顶部和左侧约束
  2. 设置高度限制
  3. 将宽度约束设置为与超级视图的宽度相等*重要
  4. 通过将约束转换为十进制来编辑约束的宽度

  1. 将小数点设置为您想要的宽度(在我的情况下为 0.5 或一半)

【讨论】:

    【解决方案3】:

    将它们都绑定到超级视图边缘(表格视图到前缘,Web 视图到后缘)并设置约束使它们具有相同的宽度。

    【讨论】:

    • 您还需要在表格视图和 Web 视图之间设置水平间距约束。
    • 那么,现在在竖屏模式下,它们的宽度都是 384。只要给它们都设置一个当前值的宽度约束?
    • 没有。选择它们并创建“等宽”的约束。正如@rdelmar 提到的 - 确保您在表格视图的右边缘和 Web 视图的左边缘之间有约束
    • 我想我在两个视图之间有一个水平间距约束,我也设置了它们的宽度约束。但在横向模式下,tableview 占据了屏幕的三分之二。
    • 移除任何指定硬编码宽度的约束
    【解决方案4】:

    在 Swift 4 中以编程方式:

    import UIKit
    
    class ViewController: UIViewController {
    
        let halfScreenViewLeft: UIView = {
            let view = UIView()
            view.backgroundColor = .blue
            return view
        }()
    
        let halfScreenViewRight: UIView = {
            let view = UIView()
            view.backgroundColor = .red
            return view
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.addSubview(halfScreenViewLeft)
            view.addSubview(halfScreenViewRight)
    
            //Enable Autolayout
            halfScreenViewLeft.translatesAutoresizingMaskIntoConstraints = false
    
            //Place the top side of the view to the top of the screen
            halfScreenViewLeft.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
    
            //Place the left side of the view to the left of the screen.
            halfScreenViewLeft.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
    
            //Set the width of the view. The multiplier indicates that it should be half of the screen.
            halfScreenViewLeft.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5).isActive = true
    
            //Set the same height as the view´s height
            halfScreenViewLeft.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
    
            //We do the same for the right view
    
            //Enable Autolayout
            halfScreenViewRight.translatesAutoresizingMaskIntoConstraints = false
    
            //Place the top side of the view to the top of the screen
            halfScreenViewRight.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
    
            //The left position of the right view depends on the position of the right side of the left view
    
            halfScreenViewRight.leadingAnchor.constraint(equalTo: halfScreenViewLeft.trailingAnchor).isActive = true
    
            //Place the right side of the view to the right of the screen.
            halfScreenViewRight.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
    
            //Set the same height as the view´s height
            halfScreenViewRight.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
    
    
        }
    
    }
    

    【讨论】:

      【解决方案5】:

      约束系统无法读懂你的想法。你必须说出你想要的。一半就是一半。如果你想要一半,就说一半。要将视图设置为其父视图宽度的一半,请为其设置一个宽度约束,使其具有与其父视图宽度相关的 .5 乘数。

      【讨论】:

      • 您可以省略前 4 句话,最后一句是您实际提供有用信息的地方。
      • 酷,谢谢。我使用有用的信息。 “给它一个宽度约束,它的父视图宽度的乘数为 0.5。”
      • 是的,这是一个很好的答案......正是我想要的。对居高临下的语气感到遗憾。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      相关资源
      最近更新 更多