objective-c 删除所有 CALayer 的子层

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2067578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 22:46:24  来源:igfitidea点击:

Removing all CALayer's sublayers

objective-ccocoacore-animation

提问by radex

I have trouble with deleting all of layer's sublayers. I currently do this manually, but that brings unnecessary clutter. I found many topics about this in google, but no answer.

我无法删除所有图层的子图层。我目前手动执行此操作,但这会带来不必要的混乱。我在谷歌上找到了很多关于这个的话题,但没有答案。

I tried to do something like this:

我试图做这样的事情:

for(CALayer *layer in rootLayer.sublayers)
{
    [layer removeFromSublayer];
}

but it didn't work.

但它没有用。

Also, i tried to clone rootLayer.sublayers into separate NSArray, but result was the same.

另外,我试图将 rootLayer.sublayers 克隆到单独的 NSArray 中,但结果是一样的。

Any ideas?

有任何想法吗?

Edit:

编辑:

I thought it works now, but I was wrong. It works good with CALayers, but it doesn't work with CATextLayers. Any ideas?

我认为它现在有效,但我错了。它适用于 CALayers,但不适用于 CATextLayers。有任何想法吗?

回答by Pascal Bourque

The simplest way to remove all sublayers from a layer is to set the sublayer property to nil:

从图层中删除所有子图层的最简单方法是将子图层属性设置为 nil:

rootLayer.sublayers = nil;

rootLayer.sublayers = nil;

回答by Ben Gottlieb

The following should work:

以下应该工作:

for (CALayer *layer in [[rootLayer.sublayers copy] autorelease]) {
    [layer removeFromSuperlayer];
}

回答by TomH

[rootLayer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];

回答by average Joe

Swift (short version):

斯威夫特(简短版本):

layer.sublayers?.forEach { $0.removeFromSuperlayer() }

layer.sublayers?.forEach { $0.removeFromSuperlayer() }

回答by Kafu

Calling rootLayer.sublayers = nil;can cause a crash (e.g. if, under iOS 8, you call removeFromSuperview twice on the view owning rootLayer).

调用rootLayer.sublayers = nil;可能会导致崩溃(例如,如果在 iOS 8 下,您对拥有的视图调用 removeFromSuperview 两次rootLayer)。

The right way should be:

正确的方法应该是:

[[rootLayer.sublayers copy] makeObjectsPerformSelector:@selector(removeFromSuperlayer)]

[[rootLayer.sublayers copy] makeObjectsPerformSelector:@selector(removeFromSuperlayer)]

The call to copyis needed so that the array on which removeFromSuperlayeris iteratively called is not modified, otherwise an exception is raised.

copy需要调用 to以便removeFromSuperlayer迭代调用的数组不被修改,否则会引发异常。

回答by pnavk

I had to do this in Xamarin/C#. I had a UITableViewCellwith some CAShapeLayersfor borders. All of the above options (including copying the Array and then removing layers caused a crash). The approach that worked for me:

我必须在 Xamarin/C# 中执行此操作。我有UITableViewCell一些CAShapeLayers边界。以上所有选项(包括复制数组然后删除图层导致崩溃)。对我有用的方法:

When adding the CALayer, I gave it a name:

添加 时CALayer,我给它起了个名字:

    var border = new CALayer();
    border.BackgroundColor = color.CGColor;
    border.Frame = new  CGRect(x, y, width, height);
    border.Name = "borderLayerName";
    Layer.AddSublayer(border);

In PrepareForReuseon the UITableViewCell, I created a copy of the SubLayersproperty and removed anything that matched the name I assigned earlier:

PrepareForReuseUITableViewCell,我创建了该SubLayers属性的副本并删除了与我之前指定的名称匹配的任何内容:

    CALayer[] copy = new CALayer[Layer.Sublayers.Length];
    Layer.Sublayers.CopyTo(copy, 0);
    copy.FirstOrDefault(l => l.Name == "borderLayerName")?.RemoveFromSuperLayer();

No crashes.

没有崩溃。

Hope this helps!

希望这可以帮助!

回答by Nestor

Indiscriminately removing all sublayers causes nasty crashes in iOS 7, which can occur much later in the program's execution. I have tested this thoroughly using both rootLayer.sublayers = niland [rootLayer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)]. There must be a system-created layer that's getting messed up.

不加选择地删除所有子层会导致 iOS 7 中的严重崩溃,这可能会在程序执行的很晚之后发生。我已经使用rootLayer.sublayers = nil和彻底测试了这一点[rootLayer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)]。一定有一个系统创建的层被搞砸了。

You have to keep your own array of layers and remove them yourself:

您必须保留自己的图层数组并自行删除它们:

[myArrayOfLayersIAddedMyself makeObjectsPerformSelector:@selector(removeFromSuperlayer)];

回答by Amit Limje

Both setting self.view.layer.sublayers = niland [layer removeFromSuperlayer]will result in crash if UIViewcontains any subview. Best way to remove CALayerfrom superLayer is by maintaining an array of layers. For instance that array is arrayOfLayers,

如果包含任何子视图self.view.layer.sublayers = nil[layer removeFromSuperlayer]则这两个设置都会导致崩溃UIViewCALayer从 superLayer 中删除的最佳方法是维护一组图层。例如该数组是arrayOfLayers,

Everytime you add a layer on UIView.sublayeradd that layer in this array...

每次添加一个图层时UIView.sublayer,都会在此数组中添加该图层...

For example

例如

[arrayOfLayers addObject:layer];
[self.view.layer addSublayer:layer];

While removing just call this,

虽然删除只是调用这个,

[arrayOfLayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];

回答by zero3nna

I tried to delete just the first sublayer at index 0 and this worked:

我试图只删除索引 0 处的第一个子层,这有效:

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    if ([cell.contentView.layer.sublayers count] != 0) {
        [[cell.contentView.layer.sublayers objectAtIndex:0] removeFromSuperlayer];
    }

回答by KatokichiSoft

How about using reverse enumeration?

如何使用反向枚举?

NSEnumerator *enumerator = [rootLayer.sublayers reverseObjectEnumerator];
for(CALayer *layer in enumerator) {
    [layer removeFromSuperlayer];
}

Because the group in sublayers are changed during enumeration, if the order is normal. I would like to know the above code's result.

因为在枚举过程中子层中的组发生了变化,如果顺序正常。我想知道上面代码的结果。