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

我该怎么做呢?


当前回答

这只适用于OSX,因为在iOS中保留了数组的副本

在删除所有子视图时,最好从数组的末尾开始删除,并一直删除到数组的开头。这可以通过以下两行代码来实现:

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

斯威夫特1.2

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

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

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

NOTE

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

因此,代码

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

不应使用。

引用自苹果关于makeObjectsPerformSelector的文档:

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

(这是错误的方向)

其他回答

这只适用于OSX,因为在iOS中保留了数组的副本

在删除所有子视图时,最好从数组的末尾开始删除,并一直删除到数组的开头。这可以通过以下两行代码来实现:

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

斯威夫特1.2

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

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

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

NOTE

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

因此,代码

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

不应使用。

引用自苹果关于makeObjectsPerformSelector的文档:

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

(这是错误的方向)

为了删除所有子视图

- (void)makeObjectsPerformSelector:(SEL)aSelector;

用法:

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

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

如果你正在使用Swift,它就像:

subviews.map { $0.removeFromSuperview }

它在理念上与makeObjectsPerformSelector方法相似,但是具有更多的类型安全性。

试试swift 2.0

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

编辑:感谢cocoafan:这种情况是混淆的事实,NSView和UIView处理事情的方式不同。对于NSView(桌面Mac开发),你可以简单地使用以下:

[someNSView setSubviews:[NSArray array]];

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

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

感谢Tommy指出,makeObjectsPerformSelector:似乎是修改子视图数组,而它被枚举(这是NSView,但不是UIView)。

请参阅这个SO问题了解更多细节。

注意:使用这两种方法中的任何一种都会删除你的主视图包含的每个视图,如果它们没有保留在其他地方,则会释放它们。来自苹果关于removeFromSuperview的文档:

如果接收器的父视图不是nil,这个方法会释放接收器。如果您计划重用视图,请确保在调用此方法之前保留它,并确保在您完成它或将它添加到另一个视图层次结构之后适当地释放它。