iOS - How To Remove Previously Added Sublayers Of a UIView
Asked Answered
S

8

49

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!

Soneson answered 2/6, 2016 at 3:5 Comment(0)
S
77

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
Saxecoburggotha answered 2/6, 2016 at 3:11 Comment(1)
Why didn't I thought of this... -_- Thanks!Soneson
T
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()
     }
 }
Tangle answered 10/9, 2017 at 18:30 Comment(0)
P
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

Phototonus answered 17/2, 2020 at 16:5 Comment(1)
All other solutions crashed me - this one worked thank you!Blastomere
P
19

I did it in Swift 3 using popLast().

self.layer.sublayers?.popLast()
Pleuropneumonia answered 5/2, 2018 at 3:11 Comment(2)
thanks, all the other solutions were crashing when trying to remove sublayer from a a UITextArea in Swift 4Cray
Very nice. Thank you very much.Thermoscope
A
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()
            }
        }
}
Affranchise answered 21/9, 2019 at 13:33 Comment(0)
T
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];
    }
}
Temikatemp answered 20/2, 2020 at 11:22 Comment(0)
A
0
view.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
Allomerism answered 7/1, 2021 at 1:23 Comment(0)
T
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() }
Turpeth answered 15/7, 2021 at 2:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.