[ios] Remove all subviews?

When my app gets back to its root view controller, in the viewDidAppear: method I need to remove all subviews.

How can I do this?

This question is related to ios subview

The answer is


For ios6 using autolayout I had to add a little bit of code to remove the constraints too.

NSMutableArray * constraints_to_remove = [ @[] mutableCopy] ;
for( NSLayoutConstraint * constraint in tagview.constraints) {
    if( [tagview.subviews containsObject:constraint.firstItem] ||
       [tagview.subviews containsObject:constraint.secondItem] ) {
        [constraints_to_remove addObject:constraint];
    }
}
[tagview removeConstraints:constraints_to_remove];

[ [tagview subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

I'm sure theres a neater way to do this, but it worked for me. In my case I could not use a direct [tagview removeConstraints:tagview.constraints] as there were constraints set in XCode that were getting cleared.


Using Swift UIView extension:

extension UIView {
    func removeAllSubviews() {
        for subview in subviews {
            subview.removeFromSuperview()
        }
    }
}

Get all the subviews from your root controller and send each a removeFromSuperview:

NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
    [v removeFromSuperview];
}

In order to remove all subviews from superviews:

NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
    id object = [oSubView objectAtIndex:iCount];
    [object removeFromSuperview];
    iCount--;
}

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

In monotouch / xamarin.ios this worked for me:

SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);

Try this way swift 2.0

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

In objective-C, go ahead and create a category method off of the UIView class.

- (void)removeAllSubviews
{
    for (UIView *subview in self.subviews)
        [subview removeFromSuperview];
}

Use the Following code to remove all subviews.

for (UIView *view in [self.view subviews]) 
{
 [view removeFromSuperview];
}

In order to remove all subviews Syntax :

- (void)makeObjectsPerformSelector:(SEL)aSelector;

Usage :

[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

This method is present in NSArray.h file and uses NSArray(NSExtendedArray) interface


This does only apply to OSX since in iOS a copy of the array is kept

When removing all the subviews, it is a good idea to start deleting at the end of the array and keep deleting until you reach the beginning. This can be accomplished with this two lines of code:

for (int i=mySuperView.subviews.count-1; i>=0; i--)
        [[mySuperView.subviews objectAtIndex:i] removeFromSuperview];

SWIFT 1.2

for var i=mySuperView.subviews.count-1; i>=0; i-- {
    mySuperView.subviews[i].removeFromSuperview();
}

or (less efficient, but more readable)

for subview in mySuperView.subviews.reverse() {
    subview.removeFromSuperview()
}

NOTE

You should NOT remove the subviews in normal order, since it may cause a crash if a UIView instance is deleted before the removeFromSuperview message has been sent to all objects of the array. (Obviously, deleting the last element would not cause a crash)

Therefore, the code

[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

should NOT be used.

Quote from Apple documentation about makeObjectsPerformSelector:

Sends to each object in the array the message identified by a given selector, starting with the first object and continuing through the array to the last object.

(which would be the wrong direction for this purpose)


In Swift you can use a functional approach like this:

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

As a comparison, the imperative approach would look like this:

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

These code snippets only work in iOS / tvOS though, things are a little different on macOS.


If you're using Swift, it's as simple as:

subviews.map { $0.removeFromSuperview }

It's similar in philosophy to the makeObjectsPerformSelector approach, however with a little more type safety.


If you want to remove all the subviews on your UIView (here yourView), then write this code at your button click:

[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];