import UIKit
import TinyConstraints
final class CountDownStackView: UIStackView {
func configure(withData data: [[String]]) {
data.forEach { rowData in
let verticalStackView = UIStackView()
verticalStackView.axis = .vertical
verticalStackView.spacing = 8
rowData.forEach { text in
let label = UILabel()
label.text = text
label.backgroundColor = .lightGray
label.textAlignment = .center
verticalStackView.addArrangedSubview(label)
}
let horizontalStackView = UIStackView()
horizontalStackView.axis = .horizontal
horizontalStackView.spacing = 5
horizontalStackView.addArrangedSubview(verticalStackView)
let parser = UILabel()
parser.text = ":"
parser.customizeLabel(font: UIFont.systemFont(ofSize: 18),textColor: .white)
horizontalStackView.addArrangedSubview(parser)
addArrangedSubview(horizontalStackView)
}
}
}
我正在使用这个代码博客,但我找不到哪里出错了以及哪里需要修复。
第一张图片是我的代码的结果,但我试图捕捉第二张图片中的情况
let data: [[String]] = [
["02", " Hour"],
["43","minute"],
["23","second"]]
样本数据
您只需要一个水平堆栈视图,但您的代码将创建 3 个。由于
self
已经是堆栈视图,因此 self
应该是唯一的水平堆栈视图。这是你的课程的重做:
final class CountDownStackView: UIStackView {
func configure(withData data: [[String]]) {
axis = .horizontal
distribution = .equalSpacing
alignment = .center
spacing = 5
for (column, rowData) in data.enumerated() {
var labels = [UILabel]()
for (row, text) in rowData.enumerated() {
let label = UILabel(frame: .zero)
label.font = row == 0 ? .preferredFont(forTextStyle: .title1) : .preferredFont(forTextStyle: .body)
label.textColor = column + 1 == data.count ? .systemGray : .label
label.text = text
label.textAlignment = .left
labels.append(label)
}
let verticalStackView = UIStackView(arrangedSubviews: labels)
verticalStackView.axis = .vertical
verticalStackView.distribution = .equalSpacing
verticalStackView.alignment = .leading
verticalStackView.spacing = 4
addArrangedSubview(verticalStackView)
if column + 1 < data.count {
let parser = UILabel()
parser.text = ":"
parser.customizeLabel(font: UIFont.systemFont(ofSize: 18), textColor: .label)
parser.sizeToFit()
addArrangedSubview(parser)
}
}
}
}
然后用类似的方式调用它:
let data: [[String]] = [
["02", "Hour"],
["43", "Minute"],
["23", "Second"],
]
let stack = CountDownStackView()
stack.configure(withData: data)
这为您提供了一个更接近第二张图片的布局。但这两个冒号看起来不对。我会将冒号作为字符串添加到您的
data
数组中。更新类如下:
final class CountDownStackView: UIStackView {
func configure(withData data: [[String]]) {
axis = .horizontal
distribution = .equalSpacing
alignment = .center
spacing = 5
for (column, rowData) in data.enumerated() {
var labels = [UILabel]()
for (row, text) in rowData.enumerated() {
let label = UILabel(frame: .zero)
label.font = row == 0 ? .preferredFont(forTextStyle: .title1) : .preferredFont(forTextStyle: .body)
label.textColor = column + 1 == data.count ? .systemGray : .label
label.text = text
label.textAlignment = .left
labels.append(label)
}
let verticalStackView = UIStackView(arrangedSubviews: labels)
verticalStackView.axis = .vertical
verticalStackView.distribution = .equalSpacing
verticalStackView.alignment = .leading
verticalStackView.spacing = 4
addArrangedSubview(verticalStackView)
}
}
}
然后创建如下:
let data: [[String]] = [
["02", "Hour"],
[":", " "],
["43", "Minute"],
[":", " "],
["23", "Second"],
]
let stack = CountDownStackView()
stack.configure(withData: data)
这可以提供更好的布局效果。
虽然这个答案为您提供了自定义堆栈视图子类的布局问题的解决方案,但我建议整个方法对于实现某种倒计时视图来说远非理想。您当前的
CountDownStackView
使得在计时器倒计时时更新任何标签变得非常困难。
虽然我将保留另一个问题的详细信息(因为这超出了您原来问题的范围),但您确实应该创建
UIView
的子类,它使用标签的堆栈视图。它还应该使用可用于更新堆栈视图中的标签的 Timer
。