#swift #uiview #uistackview
#swift #uiview #uistackview
Вопрос:
У меня есть 2 UILabels следующим образом:
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.textColor = Constants.mainFontColor.withAlphaComponent(0.7)
label.translatesAutoresizingMaskIntoConstraints = false
label.isUserInteractionEnabled = false
label.sizeToFit()
return label
}()
private lazy var valueLabel: UILabel = {
let label = UILabel()
label.textColor = Constants.mainFontColor
label.translatesAutoresizingMaskIntoConstraints = false
label.isUserInteractionEnabled = false
label.sizeToFit()
return label
}()
Затем эти метки помещаются в UIStackView:
private lazy var stackView: UIStackView = {
let stack = UIStackView(arrangedSubviews: [titleLabel, valueLabel])
stack.translatesAutoresizingMaskIntoConstraints = false
stack.axis = .horizontal
stack.spacing = 5
stack.alignment = .firstBaseline
addSubview(stack)
return stack
}()
Затем я создаю несколько таких экземпляров, например:
private lazy var flightNumber: FuelSheetHeaderField = {
return FuelSheetHeaderField(title: FuelSheetStringsField.flightNumber.title.localized,
value: viewModel.flightNumber, titleFontSize: 17, valueFontSize: 24)
}()
Затем они помещаются в отдельный вид стека:
private lazy var flightData: UIStackView = {
let stack = UIStackView(arrangedSubviews: [flightNumber, aircraftReg, dateTime, origin])
stack.axis = .horizontal
stack.distribution = .equalSpacing
stack.spacing = Constants.standardHorizontalStackSpacing
return stack
}()
Размер шрифта заголовков равен 12, а значения имеют размер шрифта 17. За исключением одного, который настроен на размер шрифта 17 и 2 соответственно. Я пытаюсь выровнять все элементы по одной базовой линии. Я добавил следующее ограничение:
titleLabel.firstBaselineAnchor.constraint(equalTo: valueLabel.firstBaselineAnchor),
Однако эффект заключается в следующем:
Большинство элементов стека выравниваются, но, как вы можете видеть, первый элемент с более крупным шрифтом расположен выше второго. Это немного сводит меня с ума. Как я могу это исправить, чтобы все элементы в стеке выравнивались по одной и той же базовой линии.
Ответ №1:
Я думаю, у вас возникнут проблемы при попытке использовать базовые показатели в представлениях стека.
Один из вариантов — не уверен, что он будет работать для вас — это поместить все метки в один горизонтальный вид стека и использовать .setCustomSpacing()
для настройки пробелов между метками.
В качестве примера:
и с Debug -> View Debugging -> Show View Frames
:
Вот код, который я использовал для создания этого:
class AlignedStackViewController: UIViewController {
let detailsStack: UIStackView = {
let v = UIStackView()
v.axis = .vertical
v.alignment = .leading
v.distribution = .fill
v.spacing = 12
return v
}()
let dataStack: UIStackView = {
let v = UIStackView()
v.axis = .horizontal
v.alignment = .firstBaseline
v.distribution = .fill
v.spacing = 5
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(red: 0.928, green: 0.973, blue: 1.0, alpha: 1.0)
let fdLabel = UILabel()
fdLabel.text = "FLIGHT DETAILS"
detailsStack.addArrangedSubview(fdLabel)
detailsStack.addArrangedSubview(dataStack)
detailsStack.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(detailsStack)
// respect safe area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// position stack view at 40, 100
detailsStack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
detailsStack.topAnchor.constraint(equalTo: g.topAnchor, constant: 100.0),
])
addLabelPair(with: "#", value: "VS0105", titleFontSize: 17, valueFontSize: 24)
addLabelPair(with: "Reg:", value: "GAAAA", titleFontSize: 12, valueFontSize: 17)
addLabelPair(with: "Departure:", value: "09 Sep 2020", titleFontSize: 12, valueFontSize: 17)
addLabelPair(with: "at", value: "08:34", titleFontSize: 12, valueFontSize: 17)
updateStackSpacing()
}
func updateStackSpacing() -> Void {
// make sure stack has been filled
guard dataStack.arrangedSubviews.count == 8 else {
return
}
// verbose for clarity
let flightNumberLabel = dataStack.arrangedSubviews[1]
let aircraftRegLabel = dataStack.arrangedSubviews[3]
dataStack.setCustomSpacing(12, after: flightNumberLabel)
dataStack.setCustomSpacing(12, after: aircraftRegLabel)
}
func addLabelPair(with title: String, value: String, titleFontSize: CGFloat, valueFontSize: CGFloat) -> Void {
let tLabel = UILabel()
let vLabel = UILabel()
tLabel.font = UIFont.systemFont(ofSize: titleFontSize)
vLabel.font = UIFont.systemFont(ofSize: valueFontSize)
tLabel.textColor = UIColor.black.withAlphaComponent(0.7)
vLabel.textColor = UIColor.black
tLabel.text = title
vLabel.text = value
dataStack.addArrangedSubview(tLabel)
dataStack.addArrangedSubview(vLabel)
}
}