removeFromSuperlayer不删除图层

时间:2014-05-03 23:01:00

标签: ios7 caanimation cashapelayer

我正在编写代码,允许用户暂时突出显示图像的某个部分。在我的视图类中,我使用touchesBegan,touchesMoved和touchesEnded来从屏幕上拾取UIBezierPath。我添加了一个图层的路径,描绘了路径,并使用动画将图层的不透明度从1淡化为0.两个NSLog语句确认该图层已添加到子图层数组

drawVanishingPath
{
    NSLog(@"There were %d sublayers before the path was added",[self.layer.sublayers count]);
    disappearingLayer = [[CAShapeLayer alloc] init];
    disappearingLayer.strokeColor = self.strokeColor.CGColor;
    disappearingLayer.fillColor = [UIColor clearColor].CGColor;
    disappearingLayer.lineWidth = [self.strokeSize floatValue];
    disappearingLayer.path = path.CGPath;
    [self.layer addSublayer:disappearingLayer];
    [disappearingLayer addAnimation:fadeAnimation forKey:@"opacity"];
    [fadeAnimation setValue:disappearingLayer forKey:@"parentLayer"];
    disappearingLayer.opacity = 0.0;
    NSLog(@"There are %d sublayers after adding the path",[self.layer.sublayers count]);
}

基于关于堆栈溢出的另一个问题的答案(How to remove a layer when its animation completes?)我设置了动画的委托并实现了animationDidStop:finished:如下所示。我添加了两个NSLog语句来确认图层已从图层数组中删除。

-(void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag
{
    NSLog(@"There were %d sublayers",[self.layer.sublayers count]);
    CAShapeLayer *layer = [animation valueForKey:@"parentLayer"];
    [layer removeAllAnimations];
    [layer removeFromSuperlayer];
    NSLog(@"There are now %d sublayers",[self.layer.sublayers count]);
}

当程序运行时,添加图层并按预期递增图层计数,但是图层计数不会在animationDidStop中减少:finished:。由于不删除图层,程序将在程序中有许多不需要的图层。这些可能会在以后引起问题。

我相信我误解了一些事情,但我不确定是什么问题。任何建议将不胜感激。

How to remove a layer when its animation completes?

1 个答案:

答案 0 :(得分:2)

你走在正确的轨道上!问题是这些问题:

[disappearingLayer addAnimation:fadeAnimation forKey:@"opacity"];
[fadeAnimation setValue:disappearingLayer forKey:@"parentLayer"];

他们的顺序错了!扭转他们的秩序,一切都会顺利。

原因是:在将动画添加到图层后,您无法修改动画。嗯,你可以,但它没有好处:动画已被复制,所以你正在修改的内容现在不是你添加的动画。

因此,您从未设置动画的parentLayer键。因此在委托方法中,该密钥为零,并且没有删除任何层。

作为测试,我运行了代码的简化版本,它按预期工作:

- (void)drawVanishingPath {
    NSLog(@"There were %d sublayers before the path was added",[self.layer.sublayers count]);
    CAShapeLayer* disappearingLayer = [[CAShapeLayer alloc] init];
    disappearingLayer.strokeColor = [UIColor redColor].CGColor;
    disappearingLayer.fillColor = [UIColor clearColor].CGColor;
    disappearingLayer.lineWidth = 5;
    disappearingLayer.path = _path;
    [self.layer addSublayer:disappearingLayer];

    CABasicAnimation* fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    fadeAnimation.toValue = @0;
    fadeAnimation.duration = 2;
    fadeAnimation.delegate = self;
    [fadeAnimation setValue:disappearingLayer forKey:@"parentLayer"];
    [disappearingLayer addAnimation:fadeAnimation forKey:@"opacity"];
    NSLog(@"There are %d sublayers after adding the path",[self.layer.sublayers count]);
}

-(void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag {
    NSLog(@"There were %d sublayers",[self.layer.sublayers count]);
    CAShapeLayer *layer = [animation valueForKey:@"parentLayer"];
    [layer removeAllAnimations];
    [layer removeFromSuperlayer];
    NSLog(@"There are now %d sublayers",[self.layer.sublayers count]);
}

日志显示:

2014-05-03 17:23:21.204 PathTest[5100:60b] There were 0 sublayers before the path was added
2014-05-03 17:23:21.209 PathTest[5100:60b] There are 1 sublayers after adding the path
2014-05-03 17:23:23.210 PathTest[5100:60b] There were 1 sublayers
2014-05-03 17:23:23.211 PathTest[5100:60b] There are now 0 sublayers