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];
}
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:
// 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++;
}
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:
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.)
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.
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.