48

I have a custom view which is a subclass of UIView. I added some sublayers to the custom view but now I want remove them.

I tried doing this:

self.layer.sublayers = nil;

But this will remove everything including the initial sublayers of the view.

Is there any way to achieve this? Or do I have to reinitialise a new custom view every time?

Note: App runs in iOS 7 and above.

Thanks!

JLT
  • 3,052
  • 9
  • 39
  • 86

8 Answers8

75

Keep a reference to the sublayer added Remove the sublayer from the super layer when not needed.

The code would be like:

Obj C:

[thesublayer removeFromSuperlayer]

Swift:

thesublayer.removeFromSuperlayer()

//thesublayer is the name of the layer you want to remove
Kegham K.
  • 1,589
  • 22
  • 40
luckystars
  • 1,704
  • 12
  • 12
64

Another way to remove specific layer from super layer is to assign unique string in layer.name property. Which you can compare later to identify and remove it out.

for layer in sublayers {
     if layer.name == "masklayer" {
          layer.removeFromSuperlayer()
     }
 }
Kiran Jasvanee
  • 6,362
  • 1
  • 36
  • 52
20

keeping reference is not cool, in some cases you can use

resultImageView.layer.sublayers?.filter{ $0 is CAShapeLayer }.forEach{ $0.removeFromSuperlayer() }

or to be more generic by using CALayer, which removes everything

Vanya
  • 4,973
  • 5
  • 32
  • 57
19

I did it in Swift 3 using popLast().

self.layer.sublayers?.popLast()
Pang
  • 9,564
  • 146
  • 81
  • 122
meow2x
  • 2,056
  • 22
  • 27
10

first of all you should add a name to the sublayer with theLayer.name property

after that you can extend the view like this:

extension UIView {
    func removeLayer(layerName: String) {
            for item in self.layer.sublayers ?? [] where item.name == layerName {
                    item.removeFromSuperlayer()
            }
        }
}
mohsen
  • 4,698
  • 1
  • 33
  • 54
0

Here is my solution for removing AVPlayerLayer without keeping a reference to it:

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];

    // Remove player layer when screen gone
    NSUInteger layerIndex = [self.view.layer.sublayers indexOfObjectPassingTest:^BOOL(__kindof CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        return [obj isKindOfClass:[AVPlayerLayer class]];
    }];
    if (layerIndex != NSNotFound) {
        AVPlayerLayer *playerLayer = self.view.layer.sublayers[layerIndex];
        [playerLayer removeFromSuperlayer];
    }
}
Idan Moshe
  • 1,675
  • 4
  • 28
  • 65
0
view.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
Lindemann
  • 3,336
  • 3
  • 29
  • 27
0

A blend of the safest answers:

First, set the name property on each added sublayer. In this case, adding a CAShapeLayer:

private let shapeName = "shape"
let shape = ...
shape.name = shapeName
self.layer.addSublayer(shape)

Later, remove only those named sublayers:

self.layer.sublayers?
    .filter { $0.name == self.shapeName }
    .forEach { $0.removeFromSuperlayer() }
Womble
  • 4,607
  • 2
  • 31
  • 45