Ich möchte 2 Labels (zB leftLabel, rightLabel) und lege sie horizontal, so dass leftLabel streckt und rightLabel nur ein einzelnes Zeichen passt (sagen wir ">"). Somit sind beide Etiketten Layout gerechtfertigt. So ...Programmatisch erstelltes horizontales UIStackView mit 2 selbsterstellten Labels
Dies ist der Code, den ich habe -
class StackViewController: UIViewController {
/// Main vertical outer/container stack view that pins its edges to this view in storyboard (i.e. full screen)
@IBOutlet weak private var containerStackView: UIStackView!
private var leftLabel: UILabel = {
let leftLabel = UILabel(frame: .zero)
leftLabel.font = .preferredFont(forTextStyle: .body)
leftLabel.numberOfLines = 0 // no text truncation, allows wrap
leftLabel.backgroundColor = .orange
return leftLabel
}()
private var rightLabel: UILabel = {
let rightLabel = UILabel(frame: .zero)
rightLabel.font = .preferredFont(forTextStyle: .body)
// Set CHCR as high so that label sizes itself to fit the text
rightLabel.setContentHuggingPriority(UILayoutPriorityDefaultHigh, for: .horizontal)
rightLabel.setContentCompressionResistancePriority(UILayoutPriorityDefaultHigh, for: .horizontal)
rightLabel.backgroundColor = .green
return rightLabel
}()
override func viewDidLoad() {
super.viewDidLoad()
prepareAndLoadSubViews()
// Note, the text required to be set in viewDidAppear, not viewDidLoad, otherwise rightLabel stretches to fill!!
leftLabel.text = "This is left label text that may go in multiple lines"
rightLabel.text = ">" // Always a single character
}
/// Dynamically creates a horizontal stack view, with 2 labels, in the container stack view
private func prepareAndLoadSubViews() {
/// Prepare the horizontal label stack view and add the 2 labels
let labelStackView = UIStackView(arrangedSubviews: [leftLabel, rightLabel])
labelStackView.axis = .horizontal
labelStackView.distribution = .fillProportionally
labelStackView.alignment = .top
containerStackView.addArrangedSubview(labelStackView)
containerStackView.addArrangedSubview(UIView())
}
}
Welche unten Ergebnis gibt (dh leftLabel Breite ist 0 im Hinblick Debugger) -
Hinweis: Wenn ich Text setzen Code in ViewDidAppear verschieben, dann funktioniert es gut.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Note, the text required to be set in viewDidAppear, not viewDidLoad, otherwise rightLabel stretches to fill!!
leftLabel.text = "This is left label text that may go in multiple lines"
rightLabel.text = ">" // Always a single character
}
Warum? Und können wir vor dem ViewDidLoad Prioritäten bei der Inhaltsanpassung/Komprimierung setzen?
Vielen Dank für das Ausprobieren und den Rat. Sie haben Recht, ich kann das gleiche Layout mit Einschränkungen erreichen. Aber ich habe zusätzliche Anforderungen, um RightLabel basierend auf Daten zu verbergen, d. H. LeftLabel sollte sich auf die volle Breite erstrecken. Um dies durch das automatische Layout zu erreichen, werden nur wenige zusätzliche Einschränkungen benötigt. Außerdem müsste ich in dieser Zelle in der Regel einige weitere Labels/imageview hinzufügen, also würde ich * lieber * Stack View als Constraints verwenden. – Ashok