使用 equalCentering 分布的 UIStackView
UIStackView distributing with equalCentering
我以编程方式创建了 UIStackView
并添加了 2 个视图,每个视图有 2 个子视图。这是我的示例代码:
let sv = UIStackView()
sv.axis = .horizontal
sv.alignment = .center
sv.spacing = Config.Dimensions.horizontalSpacing
sv.distribution = .equalCentering
sv.translatesAutoresizingMaskIntoConstraints = false
let viewCountStudent = UIView()
viewCountStudent.addSubview(studentCount)
viewCountStudent.addSubview(labelStudent)
studentCount.topAnchor.constraint(equalTo: viewCountStudent.topAnchor).isActive = true
studentCount.leftAnchor.constraint(equalTo: viewCountStudent.leftAnchor).isActive = true
studentCount.bottomAnchor.constraint(equalTo: viewCountStudent.bottomAnchor).isActive = true
labelStudent.topAnchor.constraint(equalTo: viewCountStudent.topAnchor).isActive = true
labelStudent.leftAnchor.constraint(equalTo: studentCount.rightAnchor, constant: 8.0).isActive = true
labelStudent.rightAnchor.constraint(equalTo: viewCountStudent.rightAnchor).isActive = true
labelStudent.bottomAnchor.constraint(equalTo: viewCountStudent.bottomAnchor).isActive = true
let viewCountLesson = UIView()
viewCountLesson.addSubview(lessonCount)
viewCountLesson.addSubview(labelLesson)
lessonCount.leftAnchor.constraint(equalTo: viewCountLesson.leftAnchor).isActive = true
lessonCount.topAnchor.constraint(equalTo: viewCountLesson.topAnchor).isActive = true
lessonCount.bottomAnchor.constraint(equalTo: viewCountLesson.bottomAnchor).isActive = true
labelLesson.leftAnchor.constraint(equalTo: lessonCount.rightAnchor, constant: 8.0).isActive = true
labelLesson.rightAnchor.constraint(equalTo: viewCountLesson.rightAnchor).isActive = true
labelLesson.topAnchor.constraint(equalTo: viewCountLesson.topAnchor).isActive = true
labelLesson.bottomAnchor.constraint(equalTo: viewCountLesson.bottomAnchor).isActive = true
sv.addArrangedSubview(viewCountLesson)
sv.addArrangedSubview(viewCountStudent)
sv.topAnchor.constraint(equalTo: divider.bottomAnchor, constant: 8.0).isActive = true
sv.leftAnchor.constraint(equalTo: divider.leftAnchor, constant: 16.0).isActive = true
sv.rightAnchor.constraint(equalTo: divider.rightAnchor, constant: -16.0).isActive = true
sv.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: -8.0).isActive = true
addSubview(sv)
它给出的布局是这样的:
上面是单杠,下面是 StackView。我想知道为什么两个视图之间的差距不是按堆栈视图平均分配的。我试图使它们以间距均匀分布为中心。有什么想法吗?
这可能有助于您理解...
三个绿色标签中的每个 "row" 都是水平堆栈视图,其中 Spacing: 8
和分布设置为:
- 填充
- 平均填充
- 按比例填充
- 等距居中
- 等间距
如您所见,使用 Distribution: Equal Centering
,堆栈视图排列其子视图,因此它们的 center 等距。
您可能想要的是两侧 和 之间的间距相等:
要获得该布局,请使用 Distribution: Fill
并在堆栈中添加一个空的 "spacer" 视图,因此您拥有:
spacer1 - viewCountLesson - spacer2 - viewCountStudent - spacer3
然后设置 spacer2 宽度等于 spacer1,spacer3 宽度等于 spacer1。
这是用于创建的代码:
class NewStackViewController: UIViewController {
let studentCount: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .yellow
v.text = "2"
return v
}()
let lessonCount: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .yellow
v.text = "1"
return v
}()
let labelStudent: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .cyan
v.text = "Students"
return v
}()
let labelLesson: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .cyan
v.text = "Lesson"
return v
}()
let divider: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .gray
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(divider)
NSLayoutConstraint.activate([
divider.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20.0),
divider.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20.0),
divider.heightAnchor.constraint(equalToConstant: 2.0),
divider.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0.0),
])
let sv = UIStackView()
sv.axis = .horizontal
sv.alignment = .fill
sv.spacing = 0 //Config.Dimensions.horizontalSpacing
sv.distribution = .fill
sv.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(sv)
NSLayoutConstraint.activate([
sv.leadingAnchor.constraint(equalTo: divider.leadingAnchor, constant: 16.0),
sv.trailingAnchor.constraint(equalTo: divider.trailingAnchor, constant: -16.0),
sv.topAnchor.constraint(equalTo: divider.bottomAnchor, constant: 8.0),
])
let viewCountStudent = UIView()
viewCountStudent.addSubview(studentCount)
viewCountStudent.addSubview(labelStudent)
studentCount.topAnchor.constraint(equalTo: viewCountStudent.topAnchor).isActive = true
studentCount.leftAnchor.constraint(equalTo: viewCountStudent.leftAnchor).isActive = true
studentCount.bottomAnchor.constraint(equalTo: viewCountStudent.bottomAnchor).isActive = true
labelStudent.topAnchor.constraint(equalTo: viewCountStudent.topAnchor).isActive = true
labelStudent.leftAnchor.constraint(equalTo: studentCount.rightAnchor, constant: 8.0).isActive = true
labelStudent.rightAnchor.constraint(equalTo: viewCountStudent.rightAnchor).isActive = true
labelStudent.bottomAnchor.constraint(equalTo: viewCountStudent.bottomAnchor).isActive = true
let viewCountLesson = UIView()
viewCountLesson.addSubview(lessonCount)
viewCountLesson.addSubview(labelLesson)
lessonCount.leftAnchor.constraint(equalTo: viewCountLesson.leftAnchor).isActive = true
lessonCount.topAnchor.constraint(equalTo: viewCountLesson.topAnchor).isActive = true
lessonCount.bottomAnchor.constraint(equalTo: viewCountLesson.bottomAnchor).isActive = true
labelLesson.leftAnchor.constraint(equalTo: lessonCount.rightAnchor, constant: 8.0).isActive = true
labelLesson.rightAnchor.constraint(equalTo: viewCountLesson.rightAnchor).isActive = true
labelLesson.topAnchor.constraint(equalTo: viewCountLesson.topAnchor).isActive = true
labelLesson.bottomAnchor.constraint(equalTo: viewCountLesson.bottomAnchor).isActive = true
let sp1 = spacerView()
let sp2 = spacerView()
let sp3 = spacerView()
sv.addArrangedSubview(sp1)
sv.addArrangedSubview(viewCountLesson)
sv.addArrangedSubview(sp2)
sv.addArrangedSubview(viewCountStudent)
sv.addArrangedSubview(sp3)
NSLayoutConstraint.activate([
sp2.widthAnchor.constraint(equalTo: sp1.widthAnchor, multiplier: 1.0),
sp3.widthAnchor.constraint(equalTo: sp1.widthAnchor, multiplier: 1.0),
])
[sp1, sp2, sp3, viewCountLesson, viewCountStudent, studentCount, labelStudent, lessonCount, labelLesson].forEach {
// set borderWidth to 1 to add borders to labels and views so we can see them
[=11=].layer.borderWidth = 0
[=11=].layer.borderColor = UIColor.lightGray.cgColor
// un-comment next line to set backgrounds to clear
//[=11=].backgroundColor = .clear
}
}
func spacerView() -> UIView {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .green
return v
}
}
我以编程方式创建了 UIStackView
并添加了 2 个视图,每个视图有 2 个子视图。这是我的示例代码:
let sv = UIStackView()
sv.axis = .horizontal
sv.alignment = .center
sv.spacing = Config.Dimensions.horizontalSpacing
sv.distribution = .equalCentering
sv.translatesAutoresizingMaskIntoConstraints = false
let viewCountStudent = UIView()
viewCountStudent.addSubview(studentCount)
viewCountStudent.addSubview(labelStudent)
studentCount.topAnchor.constraint(equalTo: viewCountStudent.topAnchor).isActive = true
studentCount.leftAnchor.constraint(equalTo: viewCountStudent.leftAnchor).isActive = true
studentCount.bottomAnchor.constraint(equalTo: viewCountStudent.bottomAnchor).isActive = true
labelStudent.topAnchor.constraint(equalTo: viewCountStudent.topAnchor).isActive = true
labelStudent.leftAnchor.constraint(equalTo: studentCount.rightAnchor, constant: 8.0).isActive = true
labelStudent.rightAnchor.constraint(equalTo: viewCountStudent.rightAnchor).isActive = true
labelStudent.bottomAnchor.constraint(equalTo: viewCountStudent.bottomAnchor).isActive = true
let viewCountLesson = UIView()
viewCountLesson.addSubview(lessonCount)
viewCountLesson.addSubview(labelLesson)
lessonCount.leftAnchor.constraint(equalTo: viewCountLesson.leftAnchor).isActive = true
lessonCount.topAnchor.constraint(equalTo: viewCountLesson.topAnchor).isActive = true
lessonCount.bottomAnchor.constraint(equalTo: viewCountLesson.bottomAnchor).isActive = true
labelLesson.leftAnchor.constraint(equalTo: lessonCount.rightAnchor, constant: 8.0).isActive = true
labelLesson.rightAnchor.constraint(equalTo: viewCountLesson.rightAnchor).isActive = true
labelLesson.topAnchor.constraint(equalTo: viewCountLesson.topAnchor).isActive = true
labelLesson.bottomAnchor.constraint(equalTo: viewCountLesson.bottomAnchor).isActive = true
sv.addArrangedSubview(viewCountLesson)
sv.addArrangedSubview(viewCountStudent)
sv.topAnchor.constraint(equalTo: divider.bottomAnchor, constant: 8.0).isActive = true
sv.leftAnchor.constraint(equalTo: divider.leftAnchor, constant: 16.0).isActive = true
sv.rightAnchor.constraint(equalTo: divider.rightAnchor, constant: -16.0).isActive = true
sv.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: -8.0).isActive = true
addSubview(sv)
它给出的布局是这样的:
上面是单杠,下面是 StackView。我想知道为什么两个视图之间的差距不是按堆栈视图平均分配的。我试图使它们以间距均匀分布为中心。有什么想法吗?
这可能有助于您理解...
三个绿色标签中的每个 "row" 都是水平堆栈视图,其中 Spacing: 8
和分布设置为:
- 填充
- 平均填充
- 按比例填充
- 等距居中
- 等间距
如您所见,使用 Distribution: Equal Centering
,堆栈视图排列其子视图,因此它们的 center 等距。
您可能想要的是两侧 和 之间的间距相等:
要获得该布局,请使用 Distribution: Fill
并在堆栈中添加一个空的 "spacer" 视图,因此您拥有:
spacer1 - viewCountLesson - spacer2 - viewCountStudent - spacer3
然后设置 spacer2 宽度等于 spacer1,spacer3 宽度等于 spacer1。
这是用于创建的代码:
class NewStackViewController: UIViewController {
let studentCount: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .yellow
v.text = "2"
return v
}()
let lessonCount: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .yellow
v.text = "1"
return v
}()
let labelStudent: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .cyan
v.text = "Students"
return v
}()
let labelLesson: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .cyan
v.text = "Lesson"
return v
}()
let divider: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .gray
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(divider)
NSLayoutConstraint.activate([
divider.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20.0),
divider.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20.0),
divider.heightAnchor.constraint(equalToConstant: 2.0),
divider.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0.0),
])
let sv = UIStackView()
sv.axis = .horizontal
sv.alignment = .fill
sv.spacing = 0 //Config.Dimensions.horizontalSpacing
sv.distribution = .fill
sv.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(sv)
NSLayoutConstraint.activate([
sv.leadingAnchor.constraint(equalTo: divider.leadingAnchor, constant: 16.0),
sv.trailingAnchor.constraint(equalTo: divider.trailingAnchor, constant: -16.0),
sv.topAnchor.constraint(equalTo: divider.bottomAnchor, constant: 8.0),
])
let viewCountStudent = UIView()
viewCountStudent.addSubview(studentCount)
viewCountStudent.addSubview(labelStudent)
studentCount.topAnchor.constraint(equalTo: viewCountStudent.topAnchor).isActive = true
studentCount.leftAnchor.constraint(equalTo: viewCountStudent.leftAnchor).isActive = true
studentCount.bottomAnchor.constraint(equalTo: viewCountStudent.bottomAnchor).isActive = true
labelStudent.topAnchor.constraint(equalTo: viewCountStudent.topAnchor).isActive = true
labelStudent.leftAnchor.constraint(equalTo: studentCount.rightAnchor, constant: 8.0).isActive = true
labelStudent.rightAnchor.constraint(equalTo: viewCountStudent.rightAnchor).isActive = true
labelStudent.bottomAnchor.constraint(equalTo: viewCountStudent.bottomAnchor).isActive = true
let viewCountLesson = UIView()
viewCountLesson.addSubview(lessonCount)
viewCountLesson.addSubview(labelLesson)
lessonCount.leftAnchor.constraint(equalTo: viewCountLesson.leftAnchor).isActive = true
lessonCount.topAnchor.constraint(equalTo: viewCountLesson.topAnchor).isActive = true
lessonCount.bottomAnchor.constraint(equalTo: viewCountLesson.bottomAnchor).isActive = true
labelLesson.leftAnchor.constraint(equalTo: lessonCount.rightAnchor, constant: 8.0).isActive = true
labelLesson.rightAnchor.constraint(equalTo: viewCountLesson.rightAnchor).isActive = true
labelLesson.topAnchor.constraint(equalTo: viewCountLesson.topAnchor).isActive = true
labelLesson.bottomAnchor.constraint(equalTo: viewCountLesson.bottomAnchor).isActive = true
let sp1 = spacerView()
let sp2 = spacerView()
let sp3 = spacerView()
sv.addArrangedSubview(sp1)
sv.addArrangedSubview(viewCountLesson)
sv.addArrangedSubview(sp2)
sv.addArrangedSubview(viewCountStudent)
sv.addArrangedSubview(sp3)
NSLayoutConstraint.activate([
sp2.widthAnchor.constraint(equalTo: sp1.widthAnchor, multiplier: 1.0),
sp3.widthAnchor.constraint(equalTo: sp1.widthAnchor, multiplier: 1.0),
])
[sp1, sp2, sp3, viewCountLesson, viewCountStudent, studentCount, labelStudent, lessonCount, labelLesson].forEach {
// set borderWidth to 1 to add borders to labels and views so we can see them
[=11=].layer.borderWidth = 0
[=11=].layer.borderColor = UIColor.lightGray.cgColor
// un-comment next line to set backgrounds to clear
//[=11=].backgroundColor = .clear
}
}
func spacerView() -> UIView {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .green
return v
}
}