how to remove subviews from scrollview?
Solution 1
To remove all the subviews from any view, you can iterate over the subviews and send each a removeFromSuperview
call:
// With some valid UIView *view:
for(UIView *subview in [view subviews]) {
[subview removeFromSuperview];
}
This is entirely unconditional, though, and will get rid of all subviews in the given view. If you want something more fine-grained, you could take any of several different approaches:
- Maintain your own arrays of views of different types so you can send them
removeFromSuperview
messages later in the same manner - Retain all your views where you create them and hold on to pointers to those views, so you can send them
removeFromSuperview
individually as necessary - Add an
if
statement to the above loop, checking for class equality. For example, to only remove all the UIButtons (or custom subclasses of UIButton) that exist in a view, you could use something like:
// Again, valid UIView *view:
for(UIView *subview in [view subviews]) {
if([subview isKindOfClass:[UIButton class]]) {
[subview removeFromSuperview];
} else {
// Do nothing - not a UIButton or subclass instance
}
}
Solution 2
An old question; but as it's the first hit on Google for this I thought I'd also make a note that there's also this method:
[[myScrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
You can't do the isKindOfClass check with this, but it's still a good solution to know about.
Edit: Another point to note is that the scrollbar of a scrollview is added as a subview to that scrollview. Thus if you iterate through all the subviews of a scrollview you will come across it. If removed it'll add itself again - but it's important to know this if you're only expecting your own UIView subclasses to be in there.
Amendment for Swift 3:
myScrollView.subviews.forEach { $0.removeFromSuperview() }
Solution 3
To add to what Tim said, I noticed that you are tagging your views. If you wanted to remove a view with a certain tag you could use:
[[myScrollView viewWithTag:myButtonTag] removeFromSuperview];
Solution 4
I don't think you should use the fast enumeration suggestion.
for(UIView *subview in [view subviews]) {
[subview removeFromSuperview];
}
Isn't this supposed to throw an exception if you change the collection being iterated? http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocFastEnumeration.html#//apple_ref/doc/uid/TP30001163-CH18-SW3
This example may be better.
NSArray *subviews = [[scroller subviews] copy];
for (UIView *subview in subviews) {
[subview removeFromSuperview];
}
[subviews release];
Solution 5
The problem with the UIScrollView and others subclass of UIView is that they contains initially some views (like the vertical and horizontal scrollbar for the UIScrollView). So i created a category of UIView to delete the Subviews filtered on the class.
For example:
[UIScrollView removeAllSubviewsOfClass:[FooView class],[BarView class],nil];
The code:
- (void)removeAllSubviewsOfClass:(Class)firstClass, ... NS_REQUIRES_NIL_TERMINATION;
- (void)removeAllSubviewsOfClass:(Class)firstClass, ...
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"FALSEPREDICATE"];
va_list args;
va_start(args, firstClass);
for (Class class = firstClass; class != nil; class = va_arg(args, Class))
{
predicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:predicate,[NSPredicate predicateWithFormat:@"self isKindOfClass:%@",class], nil]];
}
va_end(args);
[[self.subviews filteredArrayUsingPredicate:predicate] makeObjectsPerformSelector:@selector(removeFromSuperview)];
}
Comments
-
Rahul Vyas almost 2 years
how do i remove all subviews from my scrollview...
i have a uiview and a button above it in the scrollview something like this....
here is my code to add subview in scroll view
-(void)AddOneButton:(NSInteger)myButtonTag { lastButtonNumber = lastButtonNumber + 1; if ((lastButtonNumber == 1) || ((lastButtonNumber%2) == 1)) { btnLeft = 8;} else if ((lastButtonNumber == 2) || ((lastButtonNumber%2) == 0)) { btnLeft = 162; } CGRect frame1 = CGRectMake(btnLeft, btnTop, 150, 150); CGRect frame2 = CGRectMake(btnLeft, btnTop, 150, 150); UIButton *Button = [UIButton buttonWithType:UIButtonTypeCustom]; Button.frame = frame1; Button.tag = myButtonTag; [Button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside]; [Button setBackgroundColor:[UIColor clearColor]]; [Button setBackgroundImage:[UIImage imageNamed:@"WaitScreen.png"] forState:UIControlStateHighlighted]; GraphThumbViewControllerobj = [[GraphThumbViewController alloc] initWithPageNumber:[[GraphIdArray objectAtIndex:myButtonTag]intValue]]; GraphThumbViewControllerobj.view.frame=frame2; GraphThumbViewControllerobj.lblCounter.text=[NSString stringWithFormat:@"%d of %d",myButtonTag+1,flashCardsId.count]; GraphThumbViewControllerobj.lblQuestion.text=[flashCardText objectAtIndex:myButtonTag]; [myScrollView addSubview:GraphThumbViewControllerobj.view]; [myScrollView addSubview:Button]; if ((lastButtonNumber == 2) || ((lastButtonNumber%2) == 0)) { btnTop = btnTop + 162; } if (btnTop+150 > myScrollView.frame.size.height) { myScrollView.contentSize = CGSizeMake((myScrollView.frame.size.width), (btnTop+160));} }
and here is the code to remove subviews
if(myScrollView!=nil) { while ([myScrollView.subviews count] > 0) { //NSLog(@"subviews Count=%d",[[myScrollView subviews]count]); [[[myScrollView subviews] objectAtIndex:0] removeFromSuperview]; }