Search code examples
iosswiftuistackview

StackView -Swap Buttons in ArrangedSubviews


I have a UIStackView initially set with 4 buttons. If I need to later swap out the last button with a new button or back to the initial button, how can I do that?

lazy var stackView: UIStackView = {
    let sv = UIStackView()
    sv.axis = .horizontal
    sv.distribution = .fillEqually
    sv.alignment = .fill
    return sv
}()

// ...
var bt4: UIButton!
var bt5: UIButton!

// viewDidLoad
func configureStackView() {

    view.addSubview(stackView)

    stackView.addArrangedSubview(bt1)
    stackView.addArrangedSubview(bt2)
    stackView.addArrangedSubview(bt3)
    stackView.addArrangedSubview(bt4)

    // place stackView at bottom of scene
}

func swapLastButtonInStackViewWithNewButton(_ val: Bool) {

    if val {

        // if true replace bt4 in stackView with bt5

    } else {

        // if false replace bt5 in stackView with bt4
    }
}

Solution

  • You can store the arrange of stack subviews like this:

        lazy var stackViewArrangedSubviews = stackView.arrangedSubviews {
            didSet {
                setStackViewSubviews(with: stackViewArrangedSubviews)
            }
        }
    

    and then

        func setStackViewSubviews(with subviews: [UIView]) {
            stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
            subviews.forEach { stackView.addArrangedSubview($0) }
        }
    

    and finally implement the swap function like this:

        func swapLastButtonInStackViewWithNewButton(_ val: Bool) {
            
            if val {
                stackViewArrangedSubviews[3] = bt5
                // if true replace bt4 in stackView with bt5
                
            } else {
                stackViewArrangedSubviews[3] = bt4
                // if false replace bt5 in stackView with bt4
            }
        }
    

    This is not perfect, You can improve the code by your need.