[英]How to center two views in super view with greater than or equal to constraints
I made an example ViewController with two Labels to highlight my issue.我制作了一个带有两个标签的示例 ViewController 来突出我的问题。 The goal is to vertically separate the labels by 10, and then center them vertically using greater than or equal to constraints.目标是将标签垂直分隔 10,然后使用大于或等于约束将它们垂直居中。 I'm using visual format, but this should apply if I setup my constraints like view.topAnchor.constraint(greaterThan...
. I also have two constraints to horizontally layout the labels我使用的是视觉格式,但是如果我设置了我的约束,比如view.topAnchor.constraint(greaterThan...
。我也有两个约束来水平布局标签
My ViewController:我的视图控制器:
class myVC: UIViewController {
lazy var titleLabel: UILabel = {
let l = UILabel(frame: .zero)
l.translatesAutoresizingMaskIntoConstraints = false
l.text = "Hello World"
l.font = .systemFont(ofSize: 50)
l.textColor = .black
return l
}()
lazy var descLabel: UILabel = {
let l = UILabel(frame: .zero)
l.translatesAutoresizingMaskIntoConstraints = false
l.text = "description"
l.font = .systemFont(ofSize: 35)
l.textColor = .gray
return l
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
view.addSubview(titleLabel)
view.addSubview(descLabel)
titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
descLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor).isActive = true
NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(<=50)-[titleLabel]-(10)-[descLabel]-(<=50)-|", options: .init(), metrics: nil, views: ["titleLabel": titleLabel, "descLabel": descLabel]))
}
}
This results in这导致 . . From my understanding, this SHOULD separate the views by 10 pts, and center the labels vertically because in the format "V:|-(<=50)-[titleLabel]-(10)-[descLabel]-(<=50)-|"
根据我的理解,这应该将视图分隔 10 pts,并将标签垂直居中,因为格式为"V:|-(<=50)-[titleLabel]-(10)-[descLabel]-(<=50)-|"
I say that the distance between the Title Label's top and the superView's top should be at least (greaterThanOrEqualTo) 50, and the distance between the description Label's bottom and the superView's bottom should be at least 50. What should my top and bottom constraints look like if I want to center the two labels vertically?我说Title Label的顶部和superView的顶部之间的距离应该至少是(greaterThanOrEqualTo) 50,描述Label的底部和superView的底部之间的距离应该至少是50。我的顶部和底部约束应该是什么样的如果我想垂直居中两个标签?
Yes, I realize I can just set vertical and horizontal centers, but this is an example I made for a problem I can't use those for.是的,我意识到我只能设置垂直和水平中心,但这是我为无法使用它们的问题而制作的示例。 I need to be able to center the View with greater(or less) than or equal to constraints.我需要能够以大于(或小于)大于或等于约束的方式将视图居中。
It's very difficult to center elements using VFL.使用 VFL 使元素居中非常困难。
It's also difficult to center two elements unless they are embedded in a UIView
or a UIStackView
.除非将两个元素嵌入UIView
或UIStackView
否则它们也很难UIStackView
。
Here is one option by embedding the labels in a "container" UIView
:这是将标签嵌入“容器” UIView
一种选择:
class MyVC: UIViewController {
lazy var titleLabel: UILabel = {
let l = UILabel(frame: .zero)
l.translatesAutoresizingMaskIntoConstraints = false
l.text = "Hello World"
l.font = .systemFont(ofSize: 50)
l.textColor = .black
// center the text in the label - change to .left if desired
l.textAlignment = .center
return l
}()
lazy var descLabel: UILabel = {
let l = UILabel(frame: .zero)
l.translatesAutoresizingMaskIntoConstraints = false
l.text = "description"
l.font = .systemFont(ofSize: 35)
l.textColor = .gray
// center the text in the label - change to .left if desired
l.textAlignment = .center
return l
}()
lazy var containerView: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
// give the labels and containerView background colors to make it easy to see the layout
titleLabel.backgroundColor = .green
descLabel.backgroundColor = .cyan
containerView.backgroundColor = .blue
// add containerView to view
view.addSubview(containerView)
// add labels to containerView
containerView.addSubview(titleLabel)
containerView.addSubview(descLabel)
NSLayoutConstraint.activate([
// constrain titleLabel Top to containerView Top
titleLabel.topAnchor.constraint(equalTo: containerView.topAnchor),
// constrain titleLabel Leading and Trailing to containerView Leading and Trailing
titleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
titleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
// constrain descLabel Leading and Trailing to containerView Leading and Trailing
descLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
descLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
// constrain descLabel Bottom to containerView Bottom
descLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
// constrain descLabel Top 10-pts from titleLabel Bottom
descLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 10.0),
// constrain containerView centered horizontally and vertically
containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
}
}
Result:结果:
This can be achieved easily by using stackview.这可以通过使用 stackview 轻松实现。 Add both the labels in stackview and center it vertically in the superview with all other constraints(top, leading, bottom, trailing).在 stackview 中添加两个标签,并在所有其他约束(顶部、前导、底部、尾部)中将其垂直居中。 Here is the sample code of view controller for your use-case.这是您的用例的视图控制器的示例代码。
class ViewController: UIViewController {
lazy var titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "Hello \nWorld"
label.font = .systemFont(ofSize: 50)
label.backgroundColor = .orange
label.numberOfLines = 0
label.textColor = .black
return label
}()
lazy var descLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "a\n b\n c\n"
label.font = .systemFont(ofSize: 35)
label.backgroundColor = .green
label.numberOfLines = 0
label.textColor = .gray
return label
}()
lazy var contentView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.spacing = 10
stackView.distribution = .fill
return stackView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
contentView.addArrangedSubview(titleLabel)
contentView.addArrangedSubview(descLabel)
self.view.addSubview(contentView)
let constraints = [
contentView.topAnchor.constraint(greaterThanOrEqualTo: view.safeAreaLayoutGuide.topAnchor),
contentView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
contentView.bottomAnchor.constraint(lessThanOrEqualTo: view.safeAreaLayoutGuide.bottomAnchor)
]
NSLayoutConstraint.activate(constraints)
}
}
The above code will result this view and it goes on to take the top and buttom space until it meets the safeArea.上面的代码将产生这个视图,它继续占据顶部和底部空间,直到它遇到安全区域。 Moreover you can set the vertical content hugging and compression resistance priority to control which label to expand or shrink.此外,您可以设置垂直内容拥抱和压缩阻力优先级来控制扩展或收缩哪个标签。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.