Removing all CALayer's sublayers

前端 未结 15 980
说谎
说谎 2020-12-07 20:25

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

相关标签:
15条回答
  • 2020-12-07 20:38

    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.

    0 讨论(0)
  • 2020-12-07 20:41

    I have faced the same issue and found many solutions but none of them are perfect.
    Finally from above answer of pnavk i got the idea. At there the code is for Xamarin/C# users.
    The iOS version could be as below:

    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
    


    Objective-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;
    

    The above code will work for bottom border only. You can change the border side as per your requirement.
    Here before adding any layer to the controller, I have just run a for loop to check whether any border is already applied or not?
    To identify previously added border I use name property of CALayer. And compare that layer before remove from sublayers.
    I have tried the same code before using name property, but It creates random crash. But after using name property and comparing name before remove will solve the crash issue.

    I hope this will help someone.

    0 讨论(0)
  • 2020-12-07 20:41

    For swift3+,You can use this.

    yourView.layer.sublayers?.removeAll(keepingCapacity: true)

    See here: Apple API Reference

    Or you can: yourView.layer.sublayers?.forEach{ $0.removeFromSuperlayer()}

    0 讨论(0)
  • 2020-12-07 20:42

    Both setting self.view.layer.sublayers = nil and [layer removeFromSuperlayer] will result in crash if UIView contains any subview. Best way to remove CALayer from superLayer is by maintaining an array of layers. For instance that array is arrayOfLayers,

    Everytime you add a layer on UIView.sublayer add that layer in this array...

    For example

    [arrayOfLayers addObject:layer];
    [self.view.layer addSublayer:layer];
    

    While removing just call this,

    [arrayOfLayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
    
    0 讨论(0)
  • 2020-12-07 20:43

    I tried to delete just the first sublayer at index 0 and this worked:

    - (UITableViewCell *)tableView:(UITableView *)tableView
             cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        if ([cell.contentView.layer.sublayers count] != 0) {
            [[cell.contentView.layer.sublayers objectAtIndex:0] removeFromSuperlayer];
        }
    
    0 讨论(0)
  • 2020-12-07 20:46

    The simplest way to remove all sublayers from a layer is to set the sublayer property to nil:

    rootLayer.sublayers = nil;

    0 讨论(0)
提交回复
热议问题