如何从scrollview中删除子视图?

时间:2009-08-21 08:31:49

标签: objective-c iphone xcode uiscrollview

如何从滚动视图中删除所有子视图...

我在滚动视图上面有一个uiview和一个按钮,就像这样......

这是我在滚动视图中添加子视图的代码

-(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));}
}

以下是删除子视图的代码

if(myScrollView!=nil)
{
        while ([myScrollView.subviews count] > 0) {
            //NSLog(@"subviews Count=%d",[[myScrollView subviews]count]);
            [[[myScrollView subviews] objectAtIndex:0] removeFromSuperview];
}

alt text

8 个答案:

答案 0 :(得分:103)

要从任何视图中删除所有子视图,您可以遍历子视图并发送每个removeFromSuperview电话:

// With some valid UIView *view:
for(UIView *subview in [view subviews]) {
    [subview removeFromSuperview];
}

这完全是无条件的,并且将在给定视图中删除所有子视图。如果你想要更细粒度的东西,你可以采取以下几种方法中的任何一种:

  • 维护您自己的不同类型的视图数组,以便稍后以相同方式发送removeFromSuperview条消息
  • 保留您创建它们的所有视图并保留指向这些视图的指针,以便您可以根据需要单独发送removeFromSuperview
  • 在上面的循环中添加if语句,检查类是否相等。例如,要仅删除视图中存在的所有UIButtons(或UIButton的自定义子类),您可以使用以下内容:
// 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
    }
}

答案 1 :(得分:37)

一个老问题;但是因为这是谷歌的第一次打击,我想我也会记下这种方法:

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

你不能用这个检查isKindOfClass,但它仍然是一个很好的解决方案。

编辑:需要注意的另一点是滚动视图的滚动条被添加为该滚动视图的子视图。因此,如果您遍历滚动视图的所有子视图,您将遇到它。如果删除它会再次添加自己 - 但是如果你只是期望你自己的UIView子类在那里,那么知道这一点很重要。

Swift 3修正案:

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

答案 2 :(得分:9)

为了补充Tim说的话,我注意到你正在标记你的观点。如果您想删除具有特定标记的视图,可以使用:

[[myScrollView viewWithTag:myButtonTag] removeFromSuperview];

答案 3 :(得分:8)

我认为你不应该使用快速枚举建议。

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

如果更改正在迭代的集合,是不是应该抛出异常? http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocFastEnumeration.html#//apple_ref/doc/uid/TP30001163-CH18-SW3

这个例子可能更好。

NSArray *subviews = [[scroller subviews] copy];
for (UIView *subview in subviews) {
    [subview removeFromSuperview];
}
[subviews release];

答案 4 :(得分:2)

UIScrollView和UIView的其他子类的问题在于它们最初包含一些视图(如UIScrollView的垂直和水平滚动条)。所以我创建了一个UIView类别来删除在类上过滤的子视图。

例如:

[UIScrollView removeAllSubviewsOfClass:[FooView class],[BarView class],nil];

代码:

- (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)];

}

答案 5 :(得分:1)

最好最简单的方法是使用

for(UIView *subview in [scrollView subviews])
{
  [subview removeFromSuperview];
}

这确实会导致崩溃,因为基本规则是数组在枚举时不应该被修改,以防止我们可以使用

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

但有时崩溃仍然出现,因为makeObjectsPerformSelector:将枚举并执行选择器。同样在iOS 7中,ui操作被优化为比iOS 6更快地执行,因此反向迭代数组并删除

的最佳方法
NSArray *vs=[scrollView subviews];
for(int i=vs.count-1;i>=0;i--)
{
    [((UIView*)[vs objectAtIndex:i]) removeFromSuperview];
}

注意:枚举损害修改但不迭代......

答案 6 :(得分:0)

最简单,最好的方法是

 for(UIView *subview in [scrollView subviews]) {

     [subview removeFromSuperview];

 }

答案 7 :(得分:0)

for(subview) in self.scrollView.subviews {
        subview.removeFromSuperview()
}