I created a stackview with labels programatically in Swift. However, I was trying to find out how i can update the labels programmatically? (I did not use storyboard or IBOutlets)
let LabelStack: UIStackView = {
let label1: UILabel = {
let label = UILabel()
label.text = "Label 1"
label.font = .systemFont(ofSize: 14, weight: .bold)
label.numberOfLines = 0
label.backgroundColor = .clear
label.textAlignment = .left
label.sizeToFit()
return label
}()
let label2: UILabel = {
let label = UILabel()
label.text = "Label 2"
label.font = .systemFont(ofSize: 14, weight: .bold)
label.numberOfLines = 0
label.backgroundColor = .clear
label.textAlignment = .left
label.sizeToFit()
return label
}()
let stack = UIStackView(arrangedSubviews: [label1, label2])
stack.distribution = .equalSpacing
stack.spacing = 4.0
return stack
}()
When trying to update the label text with a function, I wasnt sure how to access the label properties to make this change. Normally, for a label created outside of the stack i could simply use:
func updateLabel() {
label1.text = "Updated Label 1 text"
label2.text = "Updated Label 2 text"
}
What is the syntax to use to access these label properties sitting inside the UIStackview with labels?
CodePudding user response:
You can make them outside let labelStack: UIStackView = {
let label1: UILabel = {
let label = UILabel()
label.text = "Label 1"
label.font = .systemFont(ofSize: 14, weight: .bold)
label.numberOfLines = 0
label.backgroundColor = .clear
label.textAlignment = .left
label.sizeToFit()
return label
}()
let label2: UILabel = {
let label = UILabel()
label.text = "Label 2"
label.font = .systemFont(ofSize: 14, weight: .bold)
label.numberOfLines = 0
label.backgroundColor = .clear
label.textAlignment = .left
label.sizeToFit()
return label
}()
let labelStack: UIStackView = {
let stack = UIStackView(arrangedSubviews: [label1, label2])
stack.distribution = .equalSpacing
stack.spacing = 4.0
return stack
}()
Or do this
if let label1 = labelStack.arrangedSubviews.first as? UILabel {
// proceed
}
if let label2 = labelStack.arrangedSubviews.last as? UILabel {
// proceed
}
CodePudding user response:
You can create them outside. But that will require you to add the arrangedSubviews later as it has not been initialized yet. So you could make the stackView Lazy, which waits for init to be run:
let label1: UILabel = {
let label = UILabel()
label.text = "Label 1"
label.font = .systemFont(ofSize: 14, weight: .bold)
label.numberOfLines = 0
label.backgroundColor = .clear
label.textAlignment = .left
label.sizeToFit()
return label
}()
let label2: UILabel = {
let label = UILabel()
label.text = "Label 2"
label.font = .systemFont(ofSize: 14, weight: .bold)
label.numberOfLines = 0
label.backgroundColor = .clear
label.textAlignment = .left
label.sizeToFit()
return label
}()
lazy var labelStack: UIStackView = {
let stack = UIStackView(arrangedSubviews: [label1, label2])
stack.distribution = .equalSpacing
stack.spacing = 4
return stack
}()
If you have to labels and 2 texts statically you can do this:
zip(labelStack.arrangedSubviews, ["textupdate1", "textupdate2"]).forEach { (element value) in
(element as? UILabel)?.text = value
}