objective-c 如何从滚动视图中删除子视图?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1310723/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 22:06:57  来源:igfitidea点击:

how to remove subviews from scrollview?

objective-ciphonexcodeuiscrollview

提问by Rahul Vyas

how do i remove all subviews from my scrollview...

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

i have a uiview and a button above it in the scrollview something like this....

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

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

alt text

替代文字

回答by Tim

To remove all the subviews from any view, you can iterate over the subviews and send each a removeFromSuperviewcall:

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

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

This is entirely unconditional, though, and will get rid of allsubviews 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 removeFromSuperviewmessages 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 removeFromSuperviewindividually as necessary
  • Add an ifstatement 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:
  • 维护您自己的不同类型的视图数组,以便您可以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
    }
}

回答by Wex

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.

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

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.

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

Amendment for Swift 3:

Swift 3 的修正:

myScrollView.subviews.forEach { 
[[myScrollView viewWithTag:myButtonTag] removeFromSuperview];
.removeFromSuperview() }

回答by Terry Blanchard

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:

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

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

回答by Coderdad

I don't think you should use the fast enumeration suggestion.

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

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

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

如果您更改正在迭代的集合,这不是应该抛出异常吗?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.

这个例子可能更好。

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

回答by Julien

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.

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

For example:

例如:

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

}

The code:

编码:

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

回答by RamaKrishna Chunduri

The best and easiest is to use

最好和最简单的是使用

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

This indeed causes crash as the basic rule is array shouldn't modified while being enumerated, to prevent that we can use

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

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

But sometimes crash is still appearing because makeObjectsPerformSelector: will enumerate and performs selector, Also in iOS 7 ui operations are optimized to perform more faster than in iOS 6, Hence the best way to iterate array reversely and remove

但有时仍然会出现崩溃,因为 makeObjectsPerformSelector: 将枚举并执行选择器,而且在 iOS 7 中 ui 操作被优化为比在 iOS 6 中执行得更快,因此最好的方法是反向迭代数组并删除

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

Note : enumerating harms modification but not iterating...

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

回答by johndpope

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

     [subview removeFromSuperview];

 }

回答by Shashank Kulshrestha

The easiest and Best way is

最简单和最好的方法是

##代码##