Home > Blockchain >  Access and update label.text or other UILabel properties inside a stackview programatically in Swift
Access and update label.text or other UILabel properties inside a stackview programatically in Swift

Time:11-09

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
    }
  • Related