我在uiview
的中央有一个viewcontroller
。在该uilabel
的上方(A)和下方(B)有uiview
。
我想以编程方式更改此uiview
的底部约束,以使uiview
上方和下方的距离随着屏幕尺寸的变化而彼此相等。因此,计算顶部uiview
到uilabel
的底部之间的距离(A)和底部uiview
到uilabel
的顶部之间的距离(B)除以2,然后设置底部约束常数相应。
我已经完成了计算,但是只有当我将其放在viewDidAppear
中时,它才似乎起作用,并且在用户能够看到对象之前,我需要将约束和视图放在正确的位置。在viewWillAppear
中可以这样做吗?感觉直到viewDidAppear
才可以正确设置所有元素。.我认为这与autolayout
的生命周期没有在计算之前完成有关。
let topDistance = view.frame.minY - ALabel.frame.maxY
let bottomDistance = BLabel.frame.minY - view.frame.maxY
let total = topDistance + bottomDistance
bottomConstraint.constant = total / 2
下面是所需结果的之前/之后示例,其中紫色uiview
对底部橙色uilabel
具有底部约束。例如,当屏幕尺寸增加时,我希望底部约束具有与紫色uiview
和顶部橙色uilabel
之间的距离相同的常数。顶部uilabel
的顶部具有顶部约束,底部uilabel
的底部具有底部约束。
答案 0 :(得分:0)
在更新约束后写入layoutIfNeeded
。
let topDistance = view.frame.minY - ALabel.frame.maxY
let bottomDistance = BLabel.frame.minY - view.frame.maxY
let total = topDistance + bottomDistance
bottomConstraint.constant = total / 2
self.view.layoutIfNeeded()
答案 1 :(得分:0)
当您使用View时,已经出现了当用户看到VeiwController时, 请改用viewDidLoad,您不能使用viewWillAppear,因为尚未加载View。
用于:
override func viewDidLoad() {
super.viewDidLoad()
}
您可以尝试致电
self.view.layoutIfNeeded()
答案 2 :(得分:0)
当我想以编程方式设置约束时,我通常是这样进行的:
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(v)
v.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
v.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20).isActive = true
v.heightAnchor.constraint(equalToConstant: 100).isActive = true
v.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor).isActive = true
答案 3 :(得分:0)
您可以为此使用调度队列:
DispatchQueue.main.async {
let topDistance = view.frame.minY - ALabel.frame.maxY
let bottomDistance = BLabel.frame.minY - view.frame.maxY
let total = topDistance + bottomDistance
bottomConstraint.constant = total / 2
self.view.layoutIfNeeded()
}
答案 4 :(得分:0)
尝试回答您的问题:
您是对的,该自动布局尚未完成在viewDidLoad()
甚至viewWillAppear()
中的工作。通常,当您需要进行这样的布局调整时,您想在viewDidLayoutSubviews()
中进行。来自Apple的文档:
viewDidLayoutSubviews
当视图控制器的视图的边界发生变化时,视图将调整其子视图的位置,然后系统调用此方法。
但是,如果我了解您的实际意图...
通过使用UIStackView
,您可以避免使用任何代码。
将标签,视图,按钮等嵌入垂直UIStackView
中。将属性设置为:
Alignment: Fill (or Leading or Center as suits your layout)
Distribution: Equal Spacing
Spacing: 0
将堆栈视图的顶部约束到视图顶部(加上所需的填充),将底部约束到视图底部(加上所需的填充)。
iPhone SE大小的结果:
iPhone 8尺寸的结果:
iPhone XS尺寸的结果:
而且,这是iPhone 8,其中还有一些不同高度的其他元素:
如您所见,元素之间具有相等的垂直间距,并且全部由堆栈视图处理。