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 a
The following should work:
for (CALayer *layer in [[rootLayer.sublayers copy] autorelease]) {
[layer removeFromSuperlayer];
}
Calling rootLayer.sublayers = nil;
can cause a crash (e.g. if, under iOS 8, you call removeFromSuperview twice on the view owning rootLayer
).
The right way should be:
[[rootLayer.sublayers copy] makeObjectsPerformSelector:@selector(removeFromSuperlayer)]
The call to copy
is needed so that the array on which removeFromSuperlayer
is iteratively called is not modified, otherwise an exception is raised.
[rootLayer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
I had to do this in Xamarin/C#. I had a UITableViewCell
with some CAShapeLayers
for borders. All of the above options (including copying the Array and then removing layers caused a crash). The approach that worked for me:
When adding the CALayer
, I gave it a name:
var border = new CALayer();
border.BackgroundColor = color.CGColor;
border.Frame = new CGRect(x, y, width, height);
border.Name = "borderLayerName";
Layer.AddSublayer(border);
In PrepareForReuse
on the UITableViewCell
, I created a copy of the SubLayers
property and removed anything that matched the name I assigned earlier:
CALayer[] copy = new CALayer[Layer.Sublayers.Length];
Layer.Sublayers.CopyTo(copy, 0);
copy.FirstOrDefault(l => l.Name == "borderLayerName")?.RemoveFromSuperLayer();
No crashes.
Hope this helps!
You could simply provide an identifier for the CAlayer you have added and remove it by searching for it. Like so
let spinLayer = CAShapeLayer()
spinLayer.path = UIBezierPath()
spinLayer.name = "spinLayer"
func removeAnimation() {
for layer in progressView.layer.sublayers ?? [CALayer]()
where layer.name == "spinLayer" {
layer.removeFromSuperlayer()
}
}
What about doing:
rootLayer.sublayers = @[];