Swift PureLayout:在最高的垂直居中子视图上方和下方添加 x 个填充点
Swift PureLayout: Add x points of padding above and below tallest vertically centered subview
我正在使用 PureLayout 框架并在 Swift 中编写我的 UIView。
我有一个视图,其中包含四个高度不相同的按钮。
我对这些按钮同样添加了约束 space ,并在视图中将它们垂直居中,并在末尾的按钮两侧添加了填充。但是,我不确定如何设置视图的高度/顶部约束,以便它与最高按钮的顶部之间有 8.0 点的间隙。我可以将约束添加到每个按钮的顶部和底部,以便它们都距离视图边缘 >= 8.0 像素,但这意味着视图可以垂直拉伸,同时仍保持这些约束。直到 运行 时间我才知道这些按钮中哪个最高。
我能想到的唯一选择是事先遍历我的按钮并找到最高的存储在变量中,并在进行约束时使用它,但我想知道是否有办法使用 PureLayout 来做到这一点更简单一点,无需 运行 遍历所有这些对象。是否有一种我缺少的方法说 "Make this value as small as possible while satisfying the rest of the constraints" 之类的东西我可以应用于视图的高度?
let topOffset = CGFloat(8.0)
let bottomOffset = CGFloat(8.0)
button1.autoConstrainAttribute(.top, to: .top, of: self, withOffset: topOffset, relation: NSLayoutRelation.self.autoConstrainAttribute(.bottom, to: .bottom, of: button1, withOffset: topOffset, relation: NSLayoutRelation.greaterThanOrEqual)
button2.autoConstrainAttribute(.top, to: .top, of: self, withOffset: topOffset, relation: NSLayoutRelation.self.autoConstrainAttribute(.bottom, to: .bottom, of: button2, withOffset: topOffset, relation: NSLayoutRelation.greaterThanOrEqual)
button3.autoConstrainAttribute(.top, to: .top, of: self, withOffset: topOffset, relation: NSLayoutRelation.self.autoConstrainAttribute(.bottom, to: .bottom, of: button3, withOffset: topOffset, relation: NSLayoutRelation.greaterThanOrEqual)
button4.autoConstrainAttribute(.top, to: .top, of: self, withOffset: topOffset, relation: NSLayoutRelation.self.autoConstrainAttribute(.bottom, to: .bottom, of: button4, withOffset: topOffset, relation: NSLayoutRelation.greaterThanOrEqual)
//MISSING: Somehow make self's height as small as possible
对于草率,我深表歉意,但这是我的目标图像。忽略水平间距。矩形是视图,圆圈是按钮,大小不一。视图需要有 8.0 点的填充 above/below 这些按钮中最高的,即本例中的蓝色按钮。它们都在视图中垂直居中,我不知道它们的大小,直到我在实例化视图时动态设置图像。
据我所知,这就是你想要达到的目标,对吧?
为此,您可以使用等间距的 UIStackView 作为容器,并将所有按钮作为子按钮添加到其中。堆栈视图将自动采用最高按钮的高度,并且您可以 space 从顶部伸出 8 像素。
您可以像这样混合使用容器视图和堆栈视图:
override func viewDidLoad() {
super.viewDidLoad()
let container = UIView()
container.translatesAutoresizingMaskIntoConstraints = false
container.backgroundColor = .lightGray
view.addSubview(container)
container.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
container.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.alignment = .center
stackView.distribution = .fillProportionally
stackView.spacing = 8
container.addSubview(stackView)
stackView.topAnchor.constraint(equalTo: container.topAnchor, constant: 8).isActive = true
stackView.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 8).isActive = true
container.bottomAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 8).isActive = true
container.trailingAnchor.constraint(equalTo: stackView.trailingAnchor, constant: 8).isActive = true
let buttonHeights: [CGFloat] = [30, 50, 40, 60]
for (i, buttonHeight) in buttonHeights.enumerated() {
let button = RoundButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .darkGray
button.setTitle("\(i)", for: .normal)
button.setTitleColor(.white, for: .normal)
stackView.addArrangedSubview(button)
button.heightAnchor.constraint(equalToConstant: buttonHeight).isActive = true
button.widthAnchor.constraint(equalTo: button.heightAnchor).isActive = true
}
}
注意:我的自定义RoundButton
class只是简单的设置了圆角半径,让它成为一个圆形的按钮。
结果:
我正在使用 PureLayout 框架并在 Swift 中编写我的 UIView。
我有一个视图,其中包含四个高度不相同的按钮。
我对这些按钮同样添加了约束 space ,并在视图中将它们垂直居中,并在末尾的按钮两侧添加了填充。但是,我不确定如何设置视图的高度/顶部约束,以便它与最高按钮的顶部之间有 8.0 点的间隙。我可以将约束添加到每个按钮的顶部和底部,以便它们都距离视图边缘 >= 8.0 像素,但这意味着视图可以垂直拉伸,同时仍保持这些约束。直到 运行 时间我才知道这些按钮中哪个最高。
我能想到的唯一选择是事先遍历我的按钮并找到最高的存储在变量中,并在进行约束时使用它,但我想知道是否有办法使用 PureLayout 来做到这一点更简单一点,无需 运行 遍历所有这些对象。是否有一种我缺少的方法说 "Make this value as small as possible while satisfying the rest of the constraints" 之类的东西我可以应用于视图的高度?
let topOffset = CGFloat(8.0)
let bottomOffset = CGFloat(8.0)
button1.autoConstrainAttribute(.top, to: .top, of: self, withOffset: topOffset, relation: NSLayoutRelation.self.autoConstrainAttribute(.bottom, to: .bottom, of: button1, withOffset: topOffset, relation: NSLayoutRelation.greaterThanOrEqual)
button2.autoConstrainAttribute(.top, to: .top, of: self, withOffset: topOffset, relation: NSLayoutRelation.self.autoConstrainAttribute(.bottom, to: .bottom, of: button2, withOffset: topOffset, relation: NSLayoutRelation.greaterThanOrEqual)
button3.autoConstrainAttribute(.top, to: .top, of: self, withOffset: topOffset, relation: NSLayoutRelation.self.autoConstrainAttribute(.bottom, to: .bottom, of: button3, withOffset: topOffset, relation: NSLayoutRelation.greaterThanOrEqual)
button4.autoConstrainAttribute(.top, to: .top, of: self, withOffset: topOffset, relation: NSLayoutRelation.self.autoConstrainAttribute(.bottom, to: .bottom, of: button4, withOffset: topOffset, relation: NSLayoutRelation.greaterThanOrEqual)
//MISSING: Somehow make self's height as small as possible
对于草率,我深表歉意,但这是我的目标图像。忽略水平间距。矩形是视图,圆圈是按钮,大小不一。视图需要有 8.0 点的填充 above/below 这些按钮中最高的,即本例中的蓝色按钮。它们都在视图中垂直居中,我不知道它们的大小,直到我在实例化视图时动态设置图像。
据我所知,这就是你想要达到的目标,对吧?
为此,您可以使用等间距的 UIStackView 作为容器,并将所有按钮作为子按钮添加到其中。堆栈视图将自动采用最高按钮的高度,并且您可以 space 从顶部伸出 8 像素。
您可以像这样混合使用容器视图和堆栈视图:
override func viewDidLoad() {
super.viewDidLoad()
let container = UIView()
container.translatesAutoresizingMaskIntoConstraints = false
container.backgroundColor = .lightGray
view.addSubview(container)
container.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
container.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.alignment = .center
stackView.distribution = .fillProportionally
stackView.spacing = 8
container.addSubview(stackView)
stackView.topAnchor.constraint(equalTo: container.topAnchor, constant: 8).isActive = true
stackView.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 8).isActive = true
container.bottomAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 8).isActive = true
container.trailingAnchor.constraint(equalTo: stackView.trailingAnchor, constant: 8).isActive = true
let buttonHeights: [CGFloat] = [30, 50, 40, 60]
for (i, buttonHeight) in buttonHeights.enumerated() {
let button = RoundButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .darkGray
button.setTitle("\(i)", for: .normal)
button.setTitleColor(.white, for: .normal)
stackView.addArrangedSubview(button)
button.heightAnchor.constraint(equalToConstant: buttonHeight).isActive = true
button.widthAnchor.constraint(equalTo: button.heightAnchor).isActive = true
}
}
注意:我的自定义RoundButton
class只是简单的设置了圆角半径,让它成为一个圆形的按钮。
结果: