删除所有子视图?
当我的应用程序回到其根视图控制器,在viewDidAppear:
方法中,我需要删除所有子视图。
我怎样才能做到这一点?
编辑:感谢cocoafan :这种情况是由NSView
和UIView
处理事情的事实混淆。 对于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--; }