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
Removing all CALayer's sublayers
提问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:
在PrepareForReuse中UITableViewCell,我创建了该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]则这两个设置都会导致崩溃UIView。CALayer从 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.
因为在枚举过程中子层中的组发生了变化,如果顺序正常。我想知道上面代码的结果。

