[macos] How to remove all subviews of a view in Swift?

I'm looking for a simple method to remove at once all subviews from a superview instead of removing them one by one.

//I'm trying something like this, but is not working
let theSubviews : Array = container_view.subviews
for (view : NSView) in theSubviews {
    view.removeFromSuperview(container_view)
}

What I am missing?

UPDATE

My app has a main container_view. I have to add different other views as subviews to container_view in order to provide a sort of navigation.

So, when clicking the button to "open" a particular page, I need to remove allsubviews and add the new one.

UPDATE 2 - A working solution (OS X)

I guess Apple fixed it.

Now it is more easy than ever, just call:

for view in containerView.subviews{
    view.removeFromSuperview()
}

This question is related to macos view swift

The answer is


Here's another approach that allows you call the operation on any collection of UIView instances (or UIView subclasses). This makes it easy to insert things like filter after .subviews so you can be more selective, or to call this on other collections of UIViews.

extension Array where Element: UIView {
  func removeEachFromSuperview() {
    forEach {
      $0.removeFromSuperview()
    }
  }
}

Example usage:

myView.subviews.removeEachFromSuperview()

// or, for example:

myView.subivews.filter { $0 is UIImageView }.removeEachFromSuperview()

Alternatively you can accomplish the same thing with a UIView extension (though this can't be called on some arbitrary array of UIView instances):

extension UIView {
    func removeSubviews(predicate: ((UIView) -> Bool)? = nil) 
        subviews.filter(
            predicate ?? { _ in true }
        ).forEach {
            $0.removeFromSuperview()
        }
    }
}

Example usage:

myView.removeSubviews()
myView.removeSubviews { $0 is UIImageView }

For removing just subviews of a specific class - this was the only Swift code that worked for me in Xcode6.1.1. Assuming the only subviews you want to remove are of type UIButton...

for subView in nameofmysuperview.subviews {
    if subView.isKindOfClass(UIButton) {
        subView.removeFromSuperview()
    }
}

Swift 3

If you add a tag to your view you can remove a specific view.

for v in (view?.subviews)!
{
    if v.tag == 321
    {
         v.removeFromSuperview()
    }
 }

Try this:

var subViews = parentView.subviews as Array<UIView>

      for someView in subViews
      {
          someView.removeFromSuperview()
      }

UPDATE: If you are feeling adventurous then you can make an extension on the UIView as shown below:

extension UIView
{
    func removeAllSubViews()
    {
       for subView :AnyObject in self.subviews
       {
            subView.removeFromSuperview()
       }
    }

}

And call it like this:

parentView.removeAllSubViews()

For Swift 4.+

extension UIView {
     public func removeAllSubViews() {
          self.subviews.forEach({ $0.removeFromSuperview() })

}

i hope this is use full for you.


The code can be written simpler as following.

view.subviews.forEach { $0.removeFromSuperview() }

I wrote this extension:

extension UIView {
    func lf_removeAllSubviews() {
        for view in self.subviews {
            view.removeFromSuperview()
        }
    }
}

So that you can use self.view.lf_removeAllSubviews in a UIViewController. I'll put this in the swift version of my https://github.com/superarts/LFramework later, when I have more experience in swift (1 day exp so far, and yes, for API I gave up underscore).


This should be the simplest solution.

let container_view: NSView = ...
container_view.subviews = []

(see Remove all subviews? for other methods)


Note this is a MacOS question and this answer works only for MacOS. It does not work on iOS.


Swift 5

I create 2 different methods to remove subview. And it's much easier to use if we put them in extension

extension UIView {
    /// Remove all subview
    func removeAllSubviews() {
        subviews.forEach { $0.removeFromSuperview() }
    }

    /// Remove all subview with specific type
    func removeAllSubviews<T: UIView>(type: T.Type) {
        subviews
            .filter { $0.isMember(of: type) }
            .forEach { $0.removeFromSuperview() }
    }
}

For Swift 3

I did as following because just removing from superview did not erase the buttons from array.

    for k in 0..<buttons.count {

      buttons[k].removeFromSuperview()

    }


    buttons.removeAll()

you have to try this

func clearAllScrollSubView ()
{
    let theSubviews = itemsScrollView.subviews

    for (var view) in theSubviews
    {

        if view is UIView
        {
            view.removeFromSuperview()
        }

    }
}

Try this:

for view in container_view.subviews {
    view.removeFromSuperview()
}

In xcodebeta6 this worked out.

    var subViews = self.parentView.subviews
    for subview in subViews as [UIView]   {
        subview.removeFromSuperview()
    }

Try this out , I tested this :

  let theSubviews = container_view.subviews
  for subview in theSubviews {
      subview.removeFromSuperview()
  }

I don't know if you managed to resolve this but I have recently experienced a similar problem where the For loop left one view each time. I found this was because the self.subviews was mutated (maybe) when the removeFromSuperview() was called.

To fix this I did:

let subViews: Array = self.subviews.copy()
for (var subview: NSView!) in subViews
{
    subview.removeFromSuperview()
}

By doing .copy(), I could perform the removal of each subview while mutating the self.subviews array. This is because the copied array (subViews) contains all of the references to the objects and is not mutated.

EDIT: In your case I think you would use:

let theSubviews: Array = container_view.subviews.copy()
for (var view: NSView!) in theSubviews
{
    view.removeFromSuperview()
}

For iOS/Swift, to get rid of all subviews I use:

for v in view.subviews{
   v.removeFromSuperview()
}

to get rid of all subviews of a particular class (like UILabel) I use:

for v in view.subviews{
   if v is UILabel{
      v.removeFromSuperview()
   }
}

Extension for remove all subviews, it is quickly removed.

import Foundation
import UIKit

extension UIView {
    /// Remove allSubView in view
    func removeAllSubViews() {
        self.subviews.forEach({ $0.removeFromSuperview() })
    }

}

One-liner:

while view.subviews.count > 0  { (view.subviews[0] as? NSView)?.removeFromSuperview() } 

Your syntax is slightly off. Make sure you cast explicitly.

 let theSubviews : Array<NSView> = container_view.subviews as Array<NSView>
 for view in theSubviews {
     view.removeFromSuperview()
 }

did you try something like

for o : AnyObject in self.subviews {
     if let v = o as? NSView {
         v.removeFromSuperview()
     }
}

Examples related to macos

Problems with installation of Google App Engine SDK for php in OS X dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac Could not install packages due to an EnvironmentError: [Errno 13] How do I install Java on Mac OSX allowing version switching? Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) Can't compile C program on a Mac after upgrade to Mojave You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory. (mac user) How can I install a previous version of Python 3 in macOS using homebrew? Could not install packages due to a "Environment error :[error 13]: permission denied : 'usr/local/bin/f2py'"

Examples related to view

Empty brackets '[]' appearing when using .where SwiftUI - How do I change the background color of a View? Drop view if exists Difference between View and ViewGroup in Android How to make a view with rounded corners? How to remove all subviews of a view in Swift? How to get a view table query (code) in SQL Server 2008 Management Studio how to add button click event in android studio How to make CREATE OR REPLACE VIEW work in SQL Server? Android findViewById() in Custom View

Examples related to swift

Make a VStack fill the width of the screen in SwiftUI Xcode 10.2.1 Command PhaseScriptExecution failed with a nonzero exit code Command CompileSwift failed with a nonzero exit code in Xcode 10 Convert Json string to Json object in Swift 4 iOS Swift - Get the Current Local Time and Date Timestamp Xcode 9 Swift Language Version (SWIFT_VERSION) How do I use Safe Area Layout programmatically? How can I use String substring in Swift 4? 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator Safe Area of Xcode 9 The use of Swift 3 @objc inference in Swift 4 mode is deprecated?