![](/img/trans.png)
[英]How to put a UIStackview inside a UIView in Swift programatically
[英]Swift how to put vertical UIStackview / UIView inside horizontal UIStackview programatically
我正在尝试将两个 UIViews 放在一个水平 UIStackview 中。 UIViews 内部是垂直的 UIStackviews 来分隔文本(例如参见图片)。 UIView 中的垂直堆栈视图正在工作。 当我尝试将两个 UIViews 添加到水平 stackview 时,UIViews 正在重叠,我似乎无法正确分隔它们。 我怎样才能像这个例子一样隔开它。 我看不到约束中的问题。 我尝试了很多不同的解决方案,但我无法弄清楚。
声明
private let horizontalStackview: UIStackView = {
let horizontalStackview = UIStackView()
horizontalStackview.distribution = .fillEqually
horizontalStackview.axis = .horizontal
horizontalStackview.spacing = 200
uhorizontalStackview.translatesAutoresizingMaskIntoConstraints = false
return horizontalStackview
}()
private let verticalFirstUIView: UIView = {
let verticalFirstUIView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 80))
verticalFirstUIView.backgroundColor = .white
verticalFirstUIView.layer.borderWidth = 2
verticalFirstUIView.layer.borderColor = UIColor.gray.cgColor
verticalFirstUIView.translatesAutoresizingMaskIntoConstraints = false
return verticalFirstUIView
}()
private let verticalSecondUIView: UIView = {
let verticalSecondUIView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 80))
verticalSecondUIView.backgroundColor = .white
verticalSecondUIView.layer.borderWidth = 2
verticalSecondUIViewlayer.borderColor = UIColor.blue.cgColor
verticalSecondUIView.translatesAutoresizingMaskIntoConstraints = false
return verticalSecondUIView
}()
private let verticalFirstStackView: UIStackView = {
let verticalFirstStackView = UIStackView()
verticalFirstStackView.axis = .vertical
verticalFirstStackView.alignment = .center
verticalFirstStackViewdistribution = .fillEqually
verticalFirstStackViewspacing = 5
verticalFirstStackView.translatesAutoresizingMaskIntoConstraints = false
return verticalFirstStackView
}()
private let verticalSecondStackView: UIStackView = {
let verticalSecondStackView = UIStackView()
verticalSecondStackView.axis = .vertical
verticalSecondStackView.alignment = .center
verticalSecondStackViewdistribution = .fillEqually
verticalSecondStackView.spacing = 5
verticalSecondStackView.translatesAutoresizingMaskIntoConstraints = false
return verticalSecondStackView
}()
有约束的函数
func setupHorizontalStackview(){
view.addSubview(horizontalStackview)
horizontalStackview.addArrangedSubview(verticalFirstUIView)
horizontalStackview.addArrangedSubview(verticalSecondUIView)
NSLayoutConstraint.activate([
horizontalStackview.topAnchor.constraint(equalTo: labelAboveHorizontalStackView.bottomAnchor, constant: 10),
horizontalStackview.widthAnchor.constraint(equalToConstant: horizontalStackview.frame.width)
])
}
func setupVerticalFirstUIView(){
view.addSubview(verticalFirstUIView)
userSavedUIView.addSubview(verticalFirstStackView)
NSLayoutConstraint.activate([ verticalFirstUIView.topAnchor.constraint(equalTo: horizontalStackview.topAnchor),
verticalFirstUIView.widthAnchor.constraint(equalToConstant: verticalFirstUIView.frame.width)
])
}
func setupVerticalSecondUIView(){
view.addSubview(verticalSecondUIView)
verticalSecondUIView.addSubview(verticalSecondStackView)
NSLayoutConstraint.activate([
verticalSecondUIView.topAnchor.constraint(equalTo: horizontalStackview.topAnchor),
verticalSecondUIView.widthAnchor.constraint(equalToConstant: verticalSecondUIView.frame.width)
])
}
func setupverticalFirstStackView(){
view.addSubview(verticalFirstStackView)
NSLayoutConstraint.activate([
verticalFirstStackView.leadingAnchor.constraint(equalTo: verticalFirstUIView.leadingAnchor, constant: 15),
verticalFirstStackView.trailingAnchor.constraint(equalTo: verticalFirstUIView.trailingAnchor, constant: -15),
verticalFirstStackView.topAnchor.constraint(equalTo: verticalFirstUIView.topAnchor, constant: 15),
verticalFirstStackView.bottomAnchor.constraint(equalTo: verticalFirstUIView.bottomAnchor),
])
let ulText = UILabel()
let ulTextTwo = UILabel()
let ulTextThree = UILabel()
ulText.text = "text”
ulTextTwo.text = "text2”
ulTextThree.text = "text3”
verticalFirstStackView.addArrangedSubview(ulText)
verticalFirstStackView.addArrangedSubview(ulTextTwo)
verticalFirstStackView.addArrangedSubview(ulTextThree)
}
func setupverticalSecondStackView(){
view.addSubview(verticalSecondStackView)
NSLayoutConstraint.activate([
verticalSecondStackView.leadingAnchor.constraint(equalTo: verticalSecondUIView.leadingAnchor, constant: 15),
verticalSecondStackView.trailingAnchor.constraint(equalTo: verticalSecondUIView.trailingAnchor, constant: -15),
verticalSecondStackView.topAnchor.constraint(equalTo: verticalSecondUIView.topAnchor, constant: 15),
verticalSecondStackView.bottomAnchor.constraint(equalTo: verticalSecondUIView.bottomAnchor),
])
let ulText = UILabel()
let ulTextTwo = UILabel()
let ulTextThree = UILabel()
ulText.text = "text”
ulTextTwo.text = "text2”
ulTextThree.text = "text3”
verticalSecondStackView.addArrangedSubview(ulText)
verticalSecondStackView.addArrangedSubview(ulTextTwo)
verticalSecondStackView.addArrangedSubview(ulTextThree)
}
我感谢所有帮助。
首先,您有一条非常奇怪的约束线:
horizontalStackview.widthAnchor.constraint(equalToConstant: horizontalStackview.frame.width)
你告诉自动布局使水平 stackView 宽度等于它自己的宽度。 这没有任何意义。
其次,虽然将任务拆分为单独的功能可能很有价值,但它可能会让人难以理解正在发生的事情。 我建议从“内联”的所有内容开始——以及关于代码应该做什么的评论——然后如果需要,稍后再分解。
我们要做的是:
到目前为止,这几乎就是你所做的。
现在,让我们在逻辑上设置元素:
然后:
在此处查看其完成方式:
class ViewController: UIViewController {
// a label above the horizontal stack view
private let labelAboveHorizontalStackView: UILabel = {
let v = UILabel()
v.text = "Label above stack view"
v.textAlignment = .center
v.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
private let horizontalStackview: UIStackView = {
let horizontalStackview = UIStackView()
horizontalStackview.distribution = .fillEqually
horizontalStackview.axis = .horizontal
horizontalStackview.spacing = 200
horizontalStackview.translatesAutoresizingMaskIntoConstraints = false
return horizontalStackview
}()
private let verticalFirstUIView: UIView = {
let verticalFirstUIView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 80))
verticalFirstUIView.backgroundColor = .white
verticalFirstUIView.layer.borderWidth = 2
verticalFirstUIView.layer.borderColor = UIColor.gray.cgColor
verticalFirstUIView.translatesAutoresizingMaskIntoConstraints = false
return verticalFirstUIView
}()
private let verticalSecondUIView: UIView = {
let verticalSecondUIView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 80))
verticalSecondUIView.backgroundColor = .white
verticalSecondUIView.layer.borderWidth = 2
verticalSecondUIView.layer.borderColor = UIColor.blue.cgColor
verticalSecondUIView.translatesAutoresizingMaskIntoConstraints = false
return verticalSecondUIView
}()
private let verticalFirstStackView: UIStackView = {
let verticalFirstStackView = UIStackView()
verticalFirstStackView.axis = .vertical
verticalFirstStackView.alignment = .center
verticalFirstStackView.distribution = .fillEqually
verticalFirstStackView.spacing = 5
verticalFirstStackView.translatesAutoresizingMaskIntoConstraints = false
return verticalFirstStackView
}()
private let verticalSecondStackView: UIStackView = {
let verticalSecondStackView = UIStackView()
verticalSecondStackView.axis = .vertical
verticalSecondStackView.alignment = .center
verticalSecondStackView.distribution = .fillEqually
verticalSecondStackView.spacing = 5
verticalSecondStackView.translatesAutoresizingMaskIntoConstraints = false
return verticalSecondStackView
}()
override func viewDidLoad() {
super.viewDidLoad()
// add 3 labels to each vertical stack view
[verticalFirstStackView, verticalSecondStackView].forEach { sv in
let ulText = UILabel()
let ulTextTwo = UILabel()
let ulTextThree = UILabel()
ulText.text = "text"
ulTextTwo.text = "text2"
ulTextThree.text = "text3"
// let's give the labels a background color to easily see the layout
ulText.backgroundColor = .yellow
ulTextTwo.backgroundColor = .green
ulTextThree.backgroundColor = .cyan
sv.addArrangedSubview(ulText)
sv.addArrangedSubview(ulTextTwo)
sv.addArrangedSubview(ulTextThree)
}
// add each vertical stack view as a subview of "UI" views
verticalFirstUIView.addSubview(verticalFirstStackView)
verticalSecondUIView.addSubview(verticalSecondStackView)
// constrain the stack views to the "UI" views
// with 15-pts "padding" on Top / Leading / Trailing
NSLayoutConstraint.activate([
verticalFirstStackView.topAnchor.constraint(equalTo: verticalFirstUIView.topAnchor, constant: 15.0),
verticalFirstStackView.leadingAnchor.constraint(equalTo: verticalFirstUIView.leadingAnchor, constant: 15.0),
verticalFirstStackView.trailingAnchor.constraint(equalTo: verticalFirstUIView.trailingAnchor, constant: -15.0),
verticalFirstStackView.bottomAnchor.constraint(equalTo: verticalFirstUIView.bottomAnchor, constant: 0.0),
verticalSecondStackView.topAnchor.constraint(equalTo: verticalSecondUIView.topAnchor, constant: 15.0),
verticalSecondStackView.leadingAnchor.constraint(equalTo: verticalSecondUIView.leadingAnchor, constant: 15.0),
verticalSecondStackView.trailingAnchor.constraint(equalTo: verticalSecondUIView.trailingAnchor, constant: -15.0),
verticalSecondStackView.bottomAnchor.constraint(equalTo: verticalSecondUIView.bottomAnchor, constant: 0.0),
])
// add the two "UI" views to the horizontal stack view
horizontalStackview.addArrangedSubview(verticalFirstUIView)
horizontalStackview.addArrangedSubview(verticalSecondUIView)
// add the "above label" to the view
view.addSubview(labelAboveHorizontalStackView)
// add horizontal stack view to the view
view.addSubview(horizontalStackview)
// let's respect the safe area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// label 40-pts from top
labelAboveHorizontalStackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
// label centered horizontally
labelAboveHorizontalStackView.centerXAnchor.constraint(equalTo: g.centerXAnchor),
// stack view 10-pts below label
horizontalStackview.topAnchor.constraint(equalTo: labelAboveHorizontalStackView.bottomAnchor, constant: 10.0),
// allow the arranged subviews to determine the width?
// if yes, center the horizontal stack view
horizontalStackview.centerXAnchor.constraint(equalTo: g.centerXAnchor),
// let's make the "above label" the same width as the
// resulting width of the horizontal stack view
labelAboveHorizontalStackView.widthAnchor.constraint(equalTo: horizontalStackview.widthAnchor),
])
}
}
这给了我们:
如果这不是您想要的确切结果,我认为您会发现通过这种方式编码更容易遵循结构和约束设置。
同样,一旦您根据需要阐明并显示了布局结构,您就可以将代码部分拆分为单独的函数(如果您发现这样做有好处)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.