删除所有子视图?

当我的应用程序回到其根视图控制器,在viewDidAppear:方法中,我需要删除所有子视图。

我怎样才能做到这一点?

编辑:感谢cocoafan :这种情况是由NSViewUIView处理事情的事实混淆。 对于NSView (仅适用于桌面Mac开发),您可以简单地使用以下内容:

 [someNSView setSubviews:[NSArray array]]; 

对于UIView (仅适用于iOS开发),您可以安全地使用makeObjectsPerformSelector:因为subviews属性将返回子视图数组的副本

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

谢谢汤米指出, makeObjectsPerformSelector:似乎修改subviews数组枚举(它为NSView ,而不是为UIView )。

请看到这个问题的更多细节。

注意:使用这两个方法中的任何一个都会删除主视图中包含的所有视图, 并释放它们 (如果它们不保留在别处)。 从苹果的文件removeFromSuperview :

如果接收者的超视图不为零,则此方法释放接收者。 如果您打算重用该视图,请务必在调用此方法之前保留该视图,并确保在完成视图或将视图添加到另一个视图层次结构后将其释放。

从根控制器获取所有子视图,并发送每个removeFromSuperview:

 NSArray *viewsToRemove = [self.view subviews]; for (UIView *v in viewsToRemove) { [v removeFromSuperview]; } 

Swift中,你可以使用这样的function方法

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

注意:此代码已更新为Swift 2.1+语法。

作为比较,这个必要的方法看起来是这样的:

 for subview in view.subviews { subview.removeFromSuperview() } 

这些代码片段只能在iOS / tvOS中运行 ,在OS X中有些不同。

如果你想删除你的UIView的所有子视图(在这里你的视图),然后写下你的button点击代码:

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

删除所有子视图时,最好从数组末尾开始删除,并保持删除,直到到达开头。 这可以用这两行代码来完成:

 for (int i=mySuperView.subviews.count-1; i>=0; i--) [[mySuperView.subviews objectAtIndex:i] removeFromSuperview]; 

SWIFT 1.2

 for var i=mySuperView.subviews.count-1; i>=0; i-- { mySuperView.subviews[i].removeFromSuperview(); } 

或(效率较低,但更具可读性)

 for subview in mySuperView.subviews.reverse() { subview.removeFromSuperview() } 

注意

您不应该以正常顺序删除子视图,因为如果在将removeFromSuperview消息发送到数组的所有对象之前删除UIView实例,则可能会导致崩溃。 (显然,删除最后一个元素不会导致崩溃)

因此,代码

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

不应该被使用。

从苹果文档引用关于makeObjectsPerformSelector :

向数组中的每个对象发送由给定select器标识的消息,从第一个对象开始,继续到数组的最后一个对象。

(这将是错误的方向)

试试这种方式迅速2.0

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

如果你使用Swift,就像下面这样简单:

 subviews.map { $0.removeFromSuperview } 

它在哲学上与makeObjectsPerformSelector方法类似,但是具有更多的types安全性。

使用Swift UIView扩展:

 extension UIView { func removeAllSubviews() { for subview in subviews { subview.removeFromSuperview() } } } 

在Objective-C中,继续并从UIView类创build一个类别方法。

 - (void)removeAllSubviews { for (UIView *subview in self.subviews) [subview removeFromSuperview]; } 

使用以下代码删除所有子视图。

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

为了删除所有子视图语法:

 - (void)makeObjectsPerformSelector:(SEL)aSelector; 

用法:

 [self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 

此方法存在于NSArray.h文件中,并使用NSArray(NSExtendedArray)接口

对于ios6使用自动布局,我不得不添加一些代码来删除约束。

 NSMutableArray * constraints_to_remove = [ @[] mutableCopy] ; for( NSLayoutConstraint * constraint in tagview.constraints) { if( [tagview.subviews containsObject:constraint.firstItem] || [tagview.subviews containsObject:constraint.secondItem] ) { [constraints_to_remove addObject:constraint]; } } [tagview removeConstraints:constraints_to_remove]; [ [tagview subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; 

我敢肯定,这是一个更好的方式来做到这一点,但它为我工作。 在我的情况下,我不能使用直接[tagview removeConstraints:tagview.constraints]因为在XCode中设置的约束被清除。

在monotouch / xamarin.ios这工作对我来说:

 SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview); 

为了从超级视图中删除所有子视图:

 NSArray *oSubView = [self subviews]; for(int iCount = 0; iCount < [oSubView count]; iCount++) { id object = [oSubView objectAtIndex:iCount]; [object removeFromSuperview]; iCount--; }