我无法删除所有图层的子图层。我目前手动执行此操作,但这会带来不必要的混乱。我在谷歌找到了很多关于此的话题,但没有答案。
我试着这样做:
for(CALayer *layer in rootLayer.sublayers) { [layer removeFromSublayer]; }
但它不起作用。
另外,我试图将rootLayer.sublayers克隆到单独的NSArray中,但结果是一样的。
有什么想法吗?
编辑:
我觉得它现在有效,但我错了。它适用于CALayers,但它不适用于CATextLayers。有什么想法吗?
答案 0 :(得分:123)
从图层中删除所有子图层的最简单方法是将子图层属性设置为nil:
rootLayer.sublayers = nil;
答案 1 :(得分:33)
以下内容应该有效:
for (CALayer *layer in [[rootLayer.sublayers copy] autorelease]) {
[layer removeFromSuperlayer];
}
答案 2 :(得分:18)
[rootLayer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
答案 3 :(得分:10)
Swift(短版):
layer.sublayers?.forEach { $0.removeFromSuperlayer() }
答案 4 :(得分:5)
调用rootLayer.sublayers = nil;
可能会导致崩溃(例如,如果在iOS 8下,您在拥有rootLayer
的视图上调用removeFromSuperview两次。)
正确的方法应该是:
[[rootLayer.sublayers copy] makeObjectsPerformSelector:@selector(removeFromSuperlayer)]
需要调用copy
,以便不会修改迭代调用removeFromSuperlayer
的数组,否则会引发异常。
答案 5 :(得分:3)
不加选择地删除所有子图层会导致iOS 7中出现严重崩溃,这可能会在程序执行后发生。我使用rootLayer.sublayers = nil
和[rootLayer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)]
对此进行了彻底的测试。必须有一个系统创建的层搞砸了。
您必须保留自己的图层数组并自行删除它们:
[myArrayOfLayersIAddedMyself makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
答案 6 :(得分:2)
如何使用反向枚举?
NSEnumerator *enumerator = [rootLayer.sublayers reverseObjectEnumerator];
for(CALayer *layer in enumerator) {
[layer removeFromSuperlayer];
}
因为在枚举期间子层中的组被更改,所以如果顺序正常。 我想知道上面代码的结果。
答案 7 :(得分:2)
我试图删除索引0处的第一个子图层,但这很有效:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([cell.contentView.layer.sublayers count] != 0) {
[[cell.contentView.layer.sublayers objectAtIndex:0] removeFromSuperlayer];
}
答案 8 :(得分:2)
如果import ZXingObjC
class ZXingObjCWrapper {
func encode() {
let writer = ZXMultiFormatWriter.writer()
....
}
}
包含任何子视图,设置self.view.layer.sublayers = nil
和[layer removeFromSuperlayer]
都会导致崩溃。从superLayer中删除UIView
的最佳方法是维护一个图层数组。
例如,该数组是arrayOfLayers,
每次在CALayer
上添加图层时,都要在此数组中添加该图层...
例如
UIView.sublayer
删除时只需调用它,
[arrayOfLayers addObject:layer];
[self.view.layer addSublayer:layer];
答案 9 :(得分:1)
我必须在Xamarin / C#中这样做。我有UITableViewCell
个边框CAShapeLayers
。所有上述选项(包括复制数组然后删除图层都会导致崩溃)。这种方法对我有用:
添加CALayer
时,我给它起了一个名字:
var border = new CALayer();
border.BackgroundColor = color.CGColor;
border.Frame = new CGRect(x, y, width, height);
border.Name = "borderLayerName";
Layer.AddSublayer(border);
在PrepareForReuse
的{{1}}中,我创建了UITableViewCell
属性的副本,并删除了与我之前指定的名称相匹配的所有内容:
SubLayers
没有崩溃。
希望这有帮助!
答案 10 :(得分:1)
我遇到了同样的问题并找到了许多解决方案,但没有一个是完美的
终于从above answer of pnavk我得到了这个想法。那里的代码是Xamarin / C#用户。
iOS版本可能如下:
Swift 2.3
if rootLayer.sublayers?.count > 0 {
rootLayer.sublayers?.forEach {
if $0.name == "bottomBorderLayer" {
$0.removeFromSuperlayer()
}
}
}
let border = CALayer()
let height = CGFloat(1.0)
border.borderColor = UIColor.blackColor().CGColor
border.borderWidth = height
border.frame = CGRectMake(0, self.frame.size.height - height, self.frame.size.width, self.frame.size.height)
border.name = "bottomBorderLayer"
rootLayer.addSublayer(border)
rootLayer.masksToBounds = true
的目标C 强>
if (rootLayer.sublayers.count > 0) {
for (CALayer *layer in rootLayer.sublayers) {
if ([layer.name isEqualToString:@"bottomBorderLayer"]) {
[layer removeFromSuperlayer];
}
}
}
CALayer *border = [[CALayer alloc] init];
CGFloat height = 1.0;
border.borderColor = [UIColor blackColor].CGColor;
border.borderWidth = height;
border.frame = CGRectMake(0, self.view.frame.size.height - height, self.view.frame.size.width, self.view.frame.size.height);
border.name = @"bottomBorderLayer";
[rootLayer addSublayer:border];
rootLayer.masksToBounds = TRUE;
以上代码仅适用于底部边框。您可以根据自己的要求更改边框
在将任何图层添加到控制器之前,我刚刚运行了一个for循环来检查是否已经应用了任何边框?
要识别以前添加的边框,我使用CALayer的name属性。并在从子图层中删除之前比较该图层
我在使用name属性之前尝试了相同的代码,但它会创建随机崩溃。但是在使用name属性并在删除之前比较名称将解决崩溃问题
我希望这会对某人有所帮助。
答案 11 :(得分:1)
您只需提供添加的CAlayer的标识符,然后通过搜索将其删除。像这样
let spinLayer = CAShapeLayer()
spinLayer.path = UIBezierPath()
spinLayer.name = "spinLayer"
func removeAnimation() {
for layer in progressView.layer.sublayers ?? [CALayer]()
where layer.name == "spinLayer" {
layer.removeFromSuperlayer()
}
}
答案 12 :(得分:-1)
对于swift3 +,你可以使用它。
yourView.layer.sublayers?.removeAll(keepingCapacity: true)
或者您可以:
yourView.layer.sublayers?.forEach{ $0.removeFromSuperlayer()}
答案 13 :(得分:-1)
做什么:
rootLayer.sublayers = @[];
答案 14 :(得分:-2)
当然可以这样做:
self.layer.sublayers=nil;
正如Pascal Bourque所建议的那样。但是为子层属性调用setter会更好:
[self.layer setSublayers:nil];
如果有可能,请避免任何清理问题。