Skip to content

Instantly share code, notes, and snippets.

@Deub27
Created November 25, 2017 14:00
Show Gist options
  • Save Deub27/5eadbf1b77ce28abd9b630eadb95c1e2 to your computer and use it in GitHub Desktop.
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() })
}
}
@pronebird
Copy link

Is there any point to deactivate constraints given that removeFromSuperview removes them anyway?

@NikKovIos
Copy link

NikKovIos commented May 31, 2018

Removing constraints rely to this issue https://stackoverflow.com/questions/41054308/swift-crash-on-removefromsuperview but i think it's not necessary.

@shivanand217
Copy link

can you please modify to remove the first inserted or last inserted arrangedView. It will be a great help.

@shivanand217
Copy link

shivanand217 commented Sep 24, 2018

Gotcha brute force :P

extension UIStackView {
    
    func removeFirstArrangedView() {
        
        for item in arrangedSubviews {
            removeArrangedSubview(item)
            item.removeFromSuperview()
            break
        }
    }
   
   var i=1
   func removeLastArrangedView() {
        
           
    for item in arrangedSubviews {
        if i == arrangedSubviews.count {
            removeArrangedSubview(item)
            item.removeFromSuperview()
        }
        i+=1
    }
   } 
}

@magpali
Copy link

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

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

andrrrr commented Dec 10, 2019

Or you can do it like this:

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

@yasirmturk
Copy link

@finebel
Copy link

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

uvios commented Sep 17, 2020

Worked like a charm 👍

@igorleonovich
Copy link

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