【问题标题】:how to remove subviews from scrollview?如何从滚动视图中删除子视图?
【发布时间】:2010-11-21 14:18:15
【问题描述】:

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

我在滚动视图中有一个 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];
}

【问题讨论】:

    标签: objective-c iphone xcode uiscrollview


    【解决方案1】:

    一个老问题;但由于它是谷歌上的第一个热门,我想我也会记下还有这种方法:

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

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

    编辑:还有一点需要注意的是,滚动视图的滚动条是作为子视图添加到该滚动视图的。因此,如果您遍历滚动视图的所有子视图,您将遇到它。如果删除它会再次添加自己 - 但如果您只希望自己的 UIView 子类在其中,了解这一点很重要。

    对 Swift 3 的修正:

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

    【讨论】:

      【解决方案2】:
      for(subview) in self.scrollView.subviews {
              subview.removeFromSuperview()
      }
      

      【讨论】:

        【解决方案3】:

        最好和最简单的就是使用

        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];
        }
        

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

        【讨论】:

          【解决方案4】:

          最简单也是最好的方法是

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

          【讨论】:

            【解决方案5】:

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

            【讨论】:

              【解决方案6】:

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

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

              【讨论】:

                【解决方案7】:

                补充蒂姆所说的,我注意到你在标记你的观点。如果您想删除带有特定标签的视图,您可以使用:

                [[myScrollView viewWithTag:myButtonTag] removeFromSuperview];
                

                【讨论】:

                  【解决方案8】:

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

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

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

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

                  【讨论】:

                  • 这对我帮助很大。谢谢!
                  • 好伙伴。正是我需要的。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-01-25
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多