在 iOS 堆栈视图中水平居中视图
Posted
技术标签:
【中文标题】在 iOS 堆栈视图中水平居中视图【英文标题】:Center views horizontally in iOS stack view 【发布时间】:2020-03-31 14:55:42 【问题描述】:我正在尝试实现以下布局(视图水平居中):
所以我像这样设置了一个堆栈视图:
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 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 以强制居中,但这似乎是一种技巧。有什么想法吗?
【问题讨论】:
约束 ?????????? @Sh_Khan 堆栈视图的工作是自动管理其排列的视图,而无需向子视图添加额外的约束。 我的意思是约束本身而不是子视图 @Sh_Khan 你会添加什么约束?在堆栈视图上水平居中? 您能否显示将两个文本气泡添加到堆栈视图的代码? 【参考方案1】:只需在其父视图中水平居中堆栈视图即可。
以下示例使用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()
不幸的是,堆栈视图本身无法自动居中内部视图,因此您必须帮助它做到这一点。
【讨论】:
这个问题针对 uikit not swiftui 感谢您的回答。我不认为水平居中是一个选项,因为我使用的是内置在库(MessageKit)中的堆栈视图,并且不想触及那里的约束。使用两个视图作为 hack 听起来不错,但是,我不确定如何在没有第三方库的情况下在 UIKit 中执行此操作 @Cesare 等宽是原生的,只需将第一个视图的宽度约束设置为第二个视图的宽度即可。以编程方式,您可以使用 UIView 的widthAnchor
属性来设置它:)
@Sh_Khan 这个答案是用纯 UIKit 编写的,并且从 iOS9 开始工作
我会接受并添加 - 如果您使用第三方库,例如 MessageKit,您可以将容器视图 UIView
添加到将包含 的预构建堆栈视图另一个 堆栈视图,但这次您决定约束(例如水平居中)。 (不确定这是否有意义,但你去)以上是关于在 iOS 堆栈视图中水平居中视图的主要内容,如果未能解决你的问题,请参考以下文章