【发布时间】:2015-01-09 21:18:32
【问题描述】:
在纵向模式下,我在左侧有一个 tableview,在右侧有一个 webview。他们都占据了屏幕的一半。我启用了自动布局。
但是当我将屏幕旋转到横向模式时,tableview 的宽度占用不到屏幕大小的一半,而 webview 最终占用了更多,而不是它们被平均分割。
为什么会这样?无论屏幕方向如何,如何让视图仅占屏幕宽度的一半?
【问题讨论】:
标签: ios objective-c autolayout
在纵向模式下,我在左侧有一个 tableview,在右侧有一个 webview。他们都占据了屏幕的一半。我启用了自动布局。
但是当我将屏幕旋转到横向模式时,tableview 的宽度占用不到屏幕大小的一半,而 webview 最终占用了更多,而不是它们被平均分割。
为什么会这样?无论屏幕方向如何,如何让视图仅占屏幕宽度的一半?
【问题讨论】:
标签: ios objective-c autolayout
答案的前半部分解决了我们希望在视图 A(蓝色)和视图 B(红色)之间平均分割视图的情况。后半部分将解决我们希望视图 A 占据屏幕一半但视图 B 不存在的情况。
如图所示设置 blue 的自动布局约束。上、左、下 0 到 superview。红色视图的 0 右侧。
为红色视图设置相同但镜像的约束。
如果您正确完成了前两个步骤,您应该会遇到一些自动布局错误和警告:
我们还需要一个约束来修复这些错误/警告并获得我们需要的东西。
按住控件,单击并从一个视图拖动到另一个视图,然后选择“等宽”。现在我们的视图将始终保持相同的宽度。我们所有的自动布局警告和错误都会消失,无论方向或设备如何,我们的视图都将始终是屏幕的一半。
要使用 VFL 在代码中添加这些约束,我们需要以下约束:
@"H:|[blueView(==redView)][redView]|"
@"V:|[blueView]|"
@"V:|[redView]|"
现在,假设我们希望单个视图占据屏幕的一半,但我们没有另一半的视图。我们仍然可以使用自动布局来做到这一点,但它的设置略有不同。在这个例子中,我们的视图是蓝色的,它的父视图是绿色的。
这与上面的步骤 1 类似,只是我们不添加右侧约束(如果我们希望视图占据不同的一半,这显然会有所不同)。
像以前一样,我们要分配“等宽”约束。在这种情况下,从我们的视图到父视图。同样,按住控件并单击从一个拖动到另一个。
此时,我们有一个自动布局警告。自动布局希望我们的框架匹配其父级的宽度。单击警告并选择“更新约束”将输入硬编码值。我们不希望这样。
选择视图并转到其尺寸检查器。在这里,我们将能够编辑约束。
单击“等于:”约束旁边的“编辑”。我们需要更改乘数值。
我们需要将乘数值改为 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)][rightView]|"(你仍然需要垂直约束)
H:。因此,您要创建这些约束:@"H:|[leftView(==rightView)][rightView]|" 用于水平,而对于您要创建的垂直:@"V:|[leftView]|" 和 @"V:|[rightView]|"
将它们都绑定到超级视图边缘(表格视图到前缘,Web 视图到后缘)并设置约束使它们具有相同的宽度。
【讨论】:
在 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 乘数。
【讨论】: