How can I refresh the contents of a control in a UIStackView?

Viewed 4213

In Swift 3 (XCode 8.3.3) I have a control in a UIStackView. I have an array of UIImageViews, and loop through the array to populate the stack view at run time:

for voiceIcon in voiceIcons {
    let voiceView = UIImageView(image: voiceIcon)
    addArrangedSubview(voiceView)
}

These icons will sometimes become disabled (replaced with a new image), so in order to update the control, I have a function to remove all the icons so that I can re-add the appropriate ones (if there's a better way, I'm listening!):

private func resetIconsView() {
    for subUIView in self.subviews as [UIView] {
        removeArrangedSubview(subUIView)
        subUIView.removeFromSuperview()
        print("Removing")
    }
}

I've also tried

for subUIView in self.subviews as! [UIImageView] { ... }

I get the debug line "Removing" for each of the icons, but they still remain in the control and the UI. I'm new to Swift, so I'm likely not understanding something, what approach should I take?

3 Answers

I did it with an extension. You have also to remove Constraints if existing. Else this can cause some trouble.

USAGE: myStackView.removeAllArrangedSubviews()

public extension UIStackView {
    func removeAllArrangedSubviews() {

        let removedSubviews = arrangedSubviews.reduce([]) { (allSubviews, subview) -> [UIView] in
            self.removeArrangedSubview(subview)
            return allSubviews + [subview]
        }

        // Deactivate all constraints
        NSLayoutConstraint.deactivate(removedSubviews.flatMap({ $0.constraints }))

        // Remove the views from self
        removedSubviews.forEach({ $0.removeFromSuperview() })
    }
}
Related