Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 10-22-2008, 10:06 PM   #1 (permalink)
Registered Member
 
Join Date: Oct 2008
Posts: 93
Default Removing all subviews from a view

Is there a way to remove all of a view's subviews instead of removing them individually by name like in the code below?

Code:
[myView1 removeFromSuperview];
fladnag is offline   Reply With Quote
Old 10-23-2008, 01:30 AM   #2 (permalink)
Registered Member
 
RickMaddy's Avatar
 
Join Date: Oct 2008
Location: Denver, CO
Posts: 2,122
Default

What about:

Code:
for (UIView *view in self.subviews) {
    [view removeFromSuperview];
}
RickMaddy is offline   Reply With Quote
Old 10-23-2008, 02:21 AM   #3 (permalink)
Registered Member
 
Join Date: Oct 2008
Posts: 93
Default

That worked perfectly. Thank you.
fladnag is offline   Reply With Quote
Old 10-11-2009, 02:01 AM   #4 (permalink)
Registered Member
 
Join Date: Oct 2009
Posts: 14
Default

Code:
for (UIView *view in self.subviews) {
    [view removeFromSuperview];
}
The above gave me the Warning message of "UIView may not respond to -countByEnumerationWithState:objects:count: And my code crashed when I tried to run it.

I used this and it worked for me:

Code:
// Assuming *view is already set up as a UIView...

for (int i = 0; i < [[self.view subviews] count]; i++ ) {
    [[[self.view subviews] objectAtIndex:i] removeFromSuperview];
}
jshake11 is offline   Reply With Quote
Old 12-14-2009, 07:23 PM   #5 (permalink)
Registered Member
 
panzeriti's Avatar
 
Join Date: Mar 2009
Posts: 313
Default

Neither of these worked for me.

This would not compile for me:
Code:
for (UIView *view in self.subviews) {
    [view removeFromSuperview];
}
And this did not remove all subviews for some reason:

Code:
for (int i = 0; i < [[self.view subviews] count]; i++ ) {
    [[[self.view subviews] objectAtIndex:i] removeFromSuperview];
}
But what did work is as follows:
Code:
for (UIView *view in [self.view subviews]) {
    [view removeFromSuperview];
}
This method compiled and removed all subviews.
__________________
My Apps
panzeriti is offline   Reply With Quote
Old 12-14-2009, 11:22 PM   #6 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,091
Default

The first one failed because subviews is not a property of self, which is presumably your view controller. If this was a custom UIView subclass, it would probably work.

The second failed because it isn't approaching the problem correctly. If you are making the array smaller each time, you have to work backwards. If you remove the object at index 0, then the object that was at index 1 is now at index 0. But your next pass removes the object at index 1, and so on.

I'm a little surprised that the 3rd one worked, because you can't change the size of the array when doing fast enumeration. I'm going to guess that it works here because the subviews property returns a copy of the array, so you aren't messing with the actual subview array.

Somebody posted a cool array trick here a few weeks ago. I haven't tested this code, but it should be something like this:

Code:
[[[self view] subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
__________________
BriTer Ideas LLC - Code review, consulting, development. PM for pricing.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
BrianSlick is offline   Reply With Quote
Old 03-25-2010, 09:09 PM   #7 (permalink)
Registered Member
 
DenVog's Avatar
 
Join Date: Jan 2009
Location: Silicon Valley, USA
Posts: 622
Thumbs up

Quote:
Originally Posted by panzeriti View Post
Neither of these worked for me.

But what did work is as follows:
Code:
for (UIView *view in [self.view subviews]) {
    [view removeFromSuperview];
}
This method compiled and removed all subviews.
Thanks for sharing this. I ran into the same issue. Your post save me a lot of time.
DenVog is offline   Reply With Quote
Old 02-21-2011, 10:54 AM   #8 (permalink)
Registered Member
 
Join Date: Feb 2011
Posts: 1
Default

Code:
while([view.subviews count] > 0)
   [[view.subviews lastObject] removeFromSuperview];
i think that a for cycle may cause some problem with the array varying in count while removing the subviews...
mndhkr is offline   Reply With Quote
Old 02-21-2011, 11:08 AM   #9 (permalink)
Registered Member
 
Join Date: Oct 2009
Location: Amsterdam, The Netherlands
Posts: 782
Default

Quote:
Originally Posted by mndhkr View Post
Code:
while([view.subviews count] > 0)
   [[view.subviews lastObject] removeFromSuperview];
i think that a for cycle may cause some problem with the array varying in count while removing the subviews...
And thats what BrianSlick said.
__________________
If my answer helped you, you might want to help me.
Make a donation via PayPal.
TUX2K is offline   Reply With Quote
Old 02-21-2011, 12:04 PM   #10 (permalink)
Registered Member
 
Join Date: Sep 2010
Posts: 321
Default

Just to add another way:

Code:
for (int i = 0; i < [[self.view subviews] count]; i++ ) {
    [[[self.view subviews] objectAtIndex:0] removeFromSuperview];
}
mariano_donati is offline   Reply With Quote
Old 04-13-2011, 01:10 AM   #11 (permalink)
DAW
Registered Member
 
Join Date: Dec 2009
Posts: 3
Default And removing a specific type of view...

Verbose but easy to follow...

Code:
    // Clear up existing scale if we need to by removing any labels
    int i,j;
    int totalSubViews = [[self.view subviews] count];
    for (i=0,j=0; i < totalSubViews; i++ ) 
    {
        if ([[[self.view subviews] objectAtIndex:j] isKindOfClass:[UILabel class]])
        {
            UILabel *thisLabel = [[self.view subviews] objectAtIndex:j];
            NSLog (@"Removing %@",thisLabel.text);
            [thisLabel removeFromSuperview];
        }
        else
            j++;
    }
DAW is offline   Reply With Quote
Old 04-29-2011, 01:08 AM   #12 (permalink)
Registered Member
 
Join Date: May 2010
Posts: 1
Default

Quote:
Originally Posted by BrianSlick View Post
The first one failed because subviews is not a property of self, which is presumably your view controller. If this was a custom UIView subclass, it would probably work.

The second failed because it isn't approaching the problem correctly. If you are making the array smaller each time, you have to work backwards. If you remove the object at index 0, then the object that was at index 1 is now at index 0. But your next pass removes the object at index 1, and so on.

I'm a little surprised that the 3rd one worked, because you can't change the size of the array when doing fast enumeration. I'm going to guess that it works here because the subviews property returns a copy of the array, so you aren't messing with the actual subview array.

Somebody posted a cool array trick here a few weeks ago. I haven't tested this code, but it should be something like this:

Code:
[[[self view] subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
this is a good way.
qdvictory is offline   Reply With Quote
Old 07-03-2011, 06:53 PM   #13 (permalink)
Registered Member
 
Join Date: Apr 2010
Posts: 3
Thumbs up

Quote:
Originally Posted by BrianSlick View Post

Somebody posted a cool array trick here a few weeks ago. I haven't tested this code, but it should be something like this:

Code:
[[[self view] subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
This is the most elegant of the methods posted here. Thanks, Brian.
pygmybutcher is offline   Reply With Quote
Old 07-04-2011, 02:49 AM   #14 (permalink)
Nuisance Developer
 
Join Date: Jul 2009
Location: Italy
Posts: 4,691
Default

really I prefer
Code:
for (UIView *view in [self.view subviews]) {
    [view removeFromSuperview];
}
__________________
dany_dev is offline   Reply With Quote
Old 07-29-2011, 10:20 PM   #15 (permalink)
Registered Member
 
Join Date: Oct 2009
Posts: 18
Default

Quote:
Originally Posted by pygmybutcher View Post
This is the most elegant of the methods posted here. Thanks, Brian.
Elegant is a dirty word. makeObjectsPerformSelector says in the docs that you shouldn't give it something that modifies the array. removeFromSuperview does. Make a copy of the subviews array and work on it and stop trying to write one line solutions. (Same problem as a vanilla For loop affecting the array it is working over.)
CBGraham is offline   Reply With Quote
Old 07-29-2011, 11:20 PM   #16 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,091
Default

Quote:
Originally Posted by CBGraham View Post
Elegant is a dirty word. makeObjectsPerformSelector says in the docs that you shouldn't give it something that modifies the array. removeFromSuperview does. Make a copy of the subviews array and work on it and stop trying to write one line solutions. (Same problem as a vanilla For loop affecting the array it is working over.)
If you had actually read the documentation before posting, then you would know that this is unnecessary, since subviews is a copy property. Plus it is an NSArray, not an NSMutableArray, therefore it cannot be modified. So if this solution didn't work, it would crash very quickly, and this would have been noted here in this thread quite some time ago.
__________________
BriTer Ideas LLC - Code review, consulting, development. PM for pricing.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
BrianSlick is offline   Reply With Quote
Old 08-05-2011, 05:02 AM   #17 (permalink)
Token farm animal
 
sneaky's Avatar
 
Join Date: Apr 2011
Posts: 268
Default

What about when I have views within views?
Will
Code:
for (UIView *view in [self.view subviews]) {
	[view removeFromSuperview];
}
remove all subviews of subviews or will I have to nest another for loop to get rid of them safely?
sneaky is offline   Reply With Quote
Old 08-05-2011, 07:38 AM   #18 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,091
Default

Perform experiments and find out.
__________________
BriTer Ideas LLC - Code review, consulting, development. PM for pricing.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
BrianSlick is offline   Reply With Quote
Old 08-05-2011, 09:00 AM   #19 (permalink)
Token farm animal
 
sneaky's Avatar
 
Join Date: Apr 2011
Posts: 268
Default

Quote:
Originally Posted by BrianSlick View Post
Perform experiments and find out.
That would make way too much sense, can't be doing that now!

So I set up a button to place a view as a subview to self.view. On this subview I put a button that calls the remove from superview for loop.

If the loop would not remove subviews of subviews I should see a leak in instruments but I was presenting and removing the view a good few times and no leak appeared so I think we can safely say that everything is indeed removed.
sneaky is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Stats
Members: 158,475
Threads: 89,090
Posts: 380,122
Top Poster: BrianSlick (7,091)
Welcome to our newest member, drg4cen
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 03:57 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0