删除所有子视图?

时间:2010-01-28 16:20:00

标签: ios subview

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

我该怎么做?

15 个答案:

答案 0 :(得分:563)

修改:感谢cocoafan:由于NSViewUIView以不同的方式处理事情,这种情况变得混乱。对于NSView(仅限桌面Mac开发),您只需使用以下内容:

[someNSView setSubviews:[NSArray array]];

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

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

感谢Tommy指出makeObjectsPerformSelector:似乎在枚举时修改subviews数组(适用于NSView,但不适用于UIView {1}})。

有关详细信息,请参阅this SO question

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

  

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

答案 1 :(得分:170)

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

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

答案 2 :(得分:106)

Swift 中,您可以使用功能方法,如下所示:

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

作为比较,命令式方法将如下所示:

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

这些代码段仅适用于 iOS / tvOS ,但在macOS上情况略有不同。

答案 3 :(得分:13)

如果要删除UIView上的所有子视图(此处为yourView),请在按下按钮时编写此代码:

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

答案 4 :(得分:8)

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

删除所有子视图时,最好在数组末尾开始删除并继续删除,直到到达开头。这可以通过以下两行代码完成:

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()
}

注意

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

因此,代码

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

NOT 使用。

引自Apple documentation about makeObjectsPerformSelector

  

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

(为此目的,这将是错误的方向)

答案 5 :(得分:4)

试试这种方式swift 2.0

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

答案 6 :(得分:4)

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

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

答案 7 :(得分:2)

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

一样简单
subviews.map { $0.removeFromSuperview }

它在哲学上与makeObjectsPerformSelector方法相似,但更安全。

答案 8 :(得分:2)

使用Swift UIView扩展程序:

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

答案 9 :(得分:2)

在objective-C中,继续从UIView类创建一个类别方法。

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

答案 10 :(得分:1)

要删除所有子视图语法:

- (void)makeObjectsPerformSelector:(SEL)aSelector;

用法:

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

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

答案 11 :(得分:1)

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

答案 12 :(得分:0)

对于使用autolayout的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中设置的约束被清除。

答案 13 :(得分:0)

在monotouch / xamarin.ios中,这对我有用:

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

答案 14 :(得分:-10)

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

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