当我的应用程序返回到其根视图控制器时,在viewDidAppear:
方法中我需要删除所有的子视图。
我该如何做?
编辑:感谢cocoafan的帮助:由于NSView
和UIView
处理方式不同,这种情况变得混乱。对于NSView
(仅适用于桌面Mac开发),您可以简单地使用以下方法:
[someNSView setSubviews:[NSArray array]];
在iOS开发中,对于UIView
类型的对象,可以安全地使用makeObjectsPerformSelector:
方法,因为subviews
属性会返回子视图数组的一个副本。[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
感谢Tommy指出makeObjectsPerformSelector:
在枚举期间修改了subviews
数组(这对于NSView
是正确的,但对于UIView
不是)。
请参见此SO问题以获取更多详细信息。
注意:使用这两种方法之一将删除您的主视图包含的每个视图并进行释放(如果它们没有在其他地方保留)。从苹果关于removeFromSuperview的文档中可以看到:
如果接收者的父视图不为nil,则此方法会释放接收者。如果计划重用视图,请在调用此方法之前保留它,并在处理完毕后或将其添加到另一个视图层次结构之后适当释放它。
从根控制器获取所有子视图,并将每个视图发送一个removeFromSuperview:
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
self.view
。 - e.Jamesfor (UIView *v in [self.view subviews])
这样更简单。 - Frade在 Swift 中,您可以像这样使用 函数式方法(functional approach):
view.subviews.forEach { $0.removeFromSuperview() }
作为对比,命令式方法看起来是这样的:
for subview in view.subviews {
subview.removeFromSuperview()
}
这些代码片段只能在 iOS / tvOS 上工作,但在 macOS 上有些许不同。
subviews
这个UIView数组中遍历出每一个子视图,然后将其从父视图中移除。 - DeFrenZ.map
的结果。这是一个纯副作用,最好像这样处理:view.subviews.forEach() { $0.removeFromSuperview() }
。 - Martin Algesten如果您想删除UIView(这里是yourView
)上的所有子视图,则在按钮单击时编写以下代码:
[[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)];
不应使用。
Apple关于makeObjectsPerformSelector的文档引用:
向数组中的每个对象发送由给定选择器标识的消息,从第一个对象开始,通过数组继续到最后一个对象。
(这对此目的来说是错误的方向)
removeFromSuperview
完成后,UIView 将从数组中移除,如果没有其他具有强关系的实例与 UIView 存在,则 UIView 也将被删除。这可能会导致越界异常。 - Daniel[yourView subviews]
返回一个数组的COPY,因此是安全的。(请注意,在OSX上,你所说的是正确的。) - ToolmakerSteve尝试这种方式 swift 2.0
view.subviews.forEach { $0.removeFromSuperview() }
forEach
的解决方案是在你之后添加的,我没有注意到。抱歉。 - Cristikview.subviews.forEach { $0.removeFromSuperview() }
- (void)removeAllSubviews
{
for (UIView *subview in self.subviews)
[subview removeFromSuperview];
}
UIView
扩展:extension UIView {
func removeAllSubviews() {
for subview in subviews {
subview.removeFromSuperview()
}
}
}
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
UIView
返回subviews
可变数组的 副本,所以这段代码可以正常工作。然而在桌面端情况却截然不同,同样的代码会抛出异常。参见 https://dev59.com/6FPTa4cB1Zd3GeqPiFCZ - e.JamessomeUIView.Subviews.All(p => p.RemoveFromSuperview);
。 - Benoit JadinonsomeUIView.Subviews.All( v => { v.RemoveFromSuperview(); return true; } );
。个人认为更清晰明了的做法是:someUIView.Subviews.ToList().ForEach( v => v.RemoveFromSuperview() );
。 - ToolmakerSteve