在 iOS 堆栈视图中水平居中视图
Center views horizontally in iOS stack view
我正在尝试实现以下布局(视图水平居中):
所以我像这样设置了一个堆栈视图:
let quickPromptsView: UIStackView = {
let sv = UIStackView()
sv.axis = .horizontal
sv.alignment = .center
sv.distribution = .equalSpacing
sv.spacing = 10
sv.translatesAutoresizingMaskIntoConstraints = false
return sv
}()
将按钮添加到堆栈视图:
func addOptions(options: [DialogNodeOutputOptionsElement]) {
DispatchQueue.main.async {
// clear all subviews
self.quickPromptsView.subviews.forEach { (view) in
view.removeFromSuperview()
}
for option in options {
let button = QuickPromptButton()
button.setTitle(option.label, for: .normal)
button.addTarget(self, action: #selector(self.didTapQuickPrompt), for: .touchUpInside)
self.quickPromptsView.addArrangedSubview(button)
}
}
}
按钮class:
class QuickPromptButton: UIButton {
var userFacingValue: String?
var answerValue: String?
override init(frame: CGRect) {
super.init(frame: frame)
layer.borderColor = UIColor.primaryColor.cgColor
layer.borderWidth = 1
layer.cornerRadius = 15
setTitleColor(.primaryColor, for: .normal)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
这就是我添加堆栈视图的方式,我将它添加到 MessageKit
的另一个堆栈部分中
func configureQuickPromptsView() {
view.addSubview(quickPromptsView)
quickPromptsView.heightAnchor.constraint(equalToConstant: 40).isActive = true
// this stack view belongs to the MessageKit library
messageInputBar.topStackView.axis = .horizontal
messageInputBar.topStackView.distribution = .fill
messageInputBar.topStackView.addArrangedSubview(quickPromptsView)
}
然而,这是我得到的:
堆栈视图占屏幕宽度的 100%。我已经尝试了每种 distribution
类型,但没有用。我还尝试在极端处插入透明 UIView
s 以强制居中,但这似乎是一种 hack。有什么想法吗?
只需将您的堆栈视图在其父视图中水平居中。
下面的示例使用了 UIKitPlus 库(它是纯 UIKit 但声明式并支持 LivePreview,iOS9+)
UView {
UHStack {
UView {
UText("Yes")
.color(.green)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .green)
.circle()
UView {
UText("No")
.color(.red)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .red)
.circle()
UView {
UText("I don't know")
.color(.darkGray)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .darkGray)
.circle()
}
.alignment(.center)
.distribution(.equalSpacing)
.spacing(10)
.edgesToSuperview(v: 0)
.centerXInSuperview() // this will center your stack view
}
.edgesToSuperview(h: 0)
.centerYInSuperview()
或者添加两个宽度相等的视图,一个在堆栈的开头,一个在堆栈的最后一个视图。
let v1 = UView()
UHStack {
v1
UView {
UText("Yes")
.color(.green)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .green)
.circle()
UView {
UText("No")
.color(.red)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .red)
.circle()
UView {
UText("I don't know")
.color(.darkGray)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .darkGray)
.circle()
UView().width(to: v1)
}
.alignment(.center)
.spacing(10)
.edgesToSuperview(h: 0)
.centerYInSuperview()
不幸的是,堆栈视图本身无法自动将内部视图居中,因此您必须帮助它做到这一点。
我正在尝试实现以下布局(视图水平居中):
所以我像这样设置了一个堆栈视图:
let quickPromptsView: UIStackView = {
let sv = UIStackView()
sv.axis = .horizontal
sv.alignment = .center
sv.distribution = .equalSpacing
sv.spacing = 10
sv.translatesAutoresizingMaskIntoConstraints = false
return sv
}()
将按钮添加到堆栈视图:
func addOptions(options: [DialogNodeOutputOptionsElement]) {
DispatchQueue.main.async {
// clear all subviews
self.quickPromptsView.subviews.forEach { (view) in
view.removeFromSuperview()
}
for option in options {
let button = QuickPromptButton()
button.setTitle(option.label, for: .normal)
button.addTarget(self, action: #selector(self.didTapQuickPrompt), for: .touchUpInside)
self.quickPromptsView.addArrangedSubview(button)
}
}
}
按钮class:
class QuickPromptButton: UIButton {
var userFacingValue: String?
var answerValue: String?
override init(frame: CGRect) {
super.init(frame: frame)
layer.borderColor = UIColor.primaryColor.cgColor
layer.borderWidth = 1
layer.cornerRadius = 15
setTitleColor(.primaryColor, for: .normal)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
这就是我添加堆栈视图的方式,我将它添加到 MessageKit
的另一个堆栈部分中func configureQuickPromptsView() {
view.addSubview(quickPromptsView)
quickPromptsView.heightAnchor.constraint(equalToConstant: 40).isActive = true
// this stack view belongs to the MessageKit library
messageInputBar.topStackView.axis = .horizontal
messageInputBar.topStackView.distribution = .fill
messageInputBar.topStackView.addArrangedSubview(quickPromptsView)
}
然而,这是我得到的:
堆栈视图占屏幕宽度的 100%。我已经尝试了每种 distribution
类型,但没有用。我还尝试在极端处插入透明 UIView
s 以强制居中,但这似乎是一种 hack。有什么想法吗?
只需将您的堆栈视图在其父视图中水平居中。
下面的示例使用了 UIKitPlus 库(它是纯 UIKit 但声明式并支持 LivePreview,iOS9+)
UView {
UHStack {
UView {
UText("Yes")
.color(.green)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .green)
.circle()
UView {
UText("No")
.color(.red)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .red)
.circle()
UView {
UText("I don't know")
.color(.darkGray)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .darkGray)
.circle()
}
.alignment(.center)
.distribution(.equalSpacing)
.spacing(10)
.edgesToSuperview(v: 0)
.centerXInSuperview() // this will center your stack view
}
.edgesToSuperview(h: 0)
.centerYInSuperview()
或者添加两个宽度相等的视图,一个在堆栈的开头,一个在堆栈的最后一个视图。
let v1 = UView()
UHStack {
v1
UView {
UText("Yes")
.color(.green)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .green)
.circle()
UView {
UText("No")
.color(.red)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .red)
.circle()
UView {
UText("I don't know")
.color(.darkGray)
.edgesToSuperview(h: 8, v: 4)
}
.border(1, .darkGray)
.circle()
UView().width(to: v1)
}
.alignment(.center)
.spacing(10)
.edgesToSuperview(h: 0)
.centerYInSuperview()
不幸的是,堆栈视图本身无法自动将内部视图居中,因此您必须帮助它做到这一点。