Skip to content

Instantly share code, notes, and snippets.

@Deub27
Created November 25, 2017 14:00
Show Gist options
  • Select an option

  • Save Deub27/5eadbf1b77ce28abd9b630eadb95c1e2 to your computer and use it in GitHub Desktop.

Select an option

Save Deub27/5eadbf1b77ce28abd9b630eadb95c1e2 to your computer and use it in GitHub Desktop.
Remove all arranged subviews from UIStackView at once
import UIKit
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() })
}
}
@magpali
Copy link
Copy Markdown

magpali commented Jan 24, 2019

Couldn't you deactivate the constraints and removeFromSuperview inside the nextPartialResult closure?
That way you wouldn't need to run through the whole array 3 times.

Something like

@discardableResult
func removeAllArrangedSubviews() -> [UIView] {
        let removedSubviews = arrangedSubviews.reduce([]) { (removedSubviews, subview) -> [UIView] in
            self.removeArrangedSubview(subview)
            NSLayoutConstraint.deactivate(subview.constraints)
            subview.removeFromSuperview()
            return removedSubviews + [subview]
        }
        return removedSubviews
    }

@hemangshah
Copy link
Copy Markdown

If someone will confuse on how to use magpali code then here's the same:

extension UIStackView {
    @discardableResult func removeAllArrangedSubviews() -> [UIView] {
        let removedSubviews = arrangedSubviews.reduce([]) { (removedSubviews, subview) -> [UIView] in
            self.removeArrangedSubview(subview)
            NSLayoutConstraint.deactivate(subview.constraints)
            subview.removeFromSuperview()
            return removedSubviews + [subview]
        }
        return removedSubviews
    }
}

@andrrrr
Copy link
Copy Markdown

andrrrr commented Dec 10, 2019

Or you can do it like this:

stack.arrangedSubviews
            .filter({ $0 is SomeView })
            .forEach({ $0.removeFromSuperview() })

@yasirmturk
Copy link
Copy Markdown

@finebel
Copy link
Copy Markdown

finebel commented Aug 20, 2020

Please corret me if I'm wrong but from my understanding you could simply do the following to remove all arrangedSubviews:

extension UIStackView {
    func removeAllArrangedSubviews() {
        arrangedSubviews.forEach {
            self.removeArrangedSubview($0)
            NSLayoutConstraint.deactivate($0.constraints)
            $0.removeFromSuperview()
        }
    }
}

@uvios
Copy link
Copy Markdown

uvios commented Sep 17, 2020

Worked like a charm 👍

@igorleonovich
Copy link
Copy Markdown

igorleonovich commented Feb 27, 2024

Just the SnapKit version:

import UIKit
import SnapKit

extension UIStackView {
    
    func removeArrangedSubviews() {
        guard !arrangedSubviews.isEmpty else { return }
        let subviewsToRemove = arrangedSubviews.reduce([]) { allSubviews, subview -> [UIView] in
            self.removeArrangedSubview(subview)
            return allSubviews + [subview]
        }
        subviewsToRemove.forEach { subview in
            subview.snp.removeConstraints()
            subview.removeFromSuperview()
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment