简体   繁体   中英

Add views to stackview programmatically in Swift

I have a horizontal Stack View that fills the full width of the screen and contains 3 vertical StackView, that are empty when the controller is loaded. the horizontal has alignment set to fill and distribution to equal spacing and the vertical have alignments left, center, right and distribution fill equally. When the user later navigates back to this scene, I might want to fill these StackViews. Therefore I have overwritten the viewWillAppear and inside I do something like this:

DispatchQueue.global(qos: .userInitiated).async {
    // here i need to load the data for the labels
    DispatchQueue.main.async {
        var label = UILabel()
        label.text = //...
        self.firstStackView.addArrangedSubview(label)
        label = UILabel()
        label.text = //...
        self.secondStackView.addArrangedSubview(label)
        var btn = UIButton()
        btn.setTitle("X", for: .normal)
        btn.addTarget(//...)
        self.thirdStackView.addArrangedSubview(btn)
    }
}

now, I only see the button of the 3rd Stack View. Even if I do this multiple times I only see the first Button. I think it's because the stackviews are empty at first and their size don't get updated. do I have to call any function, so that it recreates all views? (but with the new subviews)

edit: I found a workaround: I add some label to each of the 3 stack views in the storyboard and remove them again in the code. it works, but I don't think this is a nice solution and if I need to remove labels again, the stackviews don't get smaller. There must be a better way.

private var lbl1: UILabel!
private var lbl2: UILabel!
private var horizontalStackView: UIStackView!

private let setupLabelBlock = { () -> UILabel in
    let label = UILabel()
    label.textColor = .white
    label.setFontSize(16)
    label.textAlignment = .center
    return label
}

private func setupSubviews() {
    setupLabels()
    setupHorizontalStackView()
}

private func setupLabels() {
    lbl1 = setupLabelBlock()
    lbl2 = setupLabelBlock()
}

private func setupHorizontalStackView() {
    horizontalStackView = UIStackView(arrangedSubviews: [lbl1, lbl2])
    horizontalStackView.axis = .horizontal
    horizontalStackView.alignment = .fill
    horizontalStackView.distribution = .fill
    horizontalStackView.spacing = 2
}

Call setupSubviews method as per requirement. I Hope, solution helpful to you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM