【问题标题】:removeFromSuperlayer not removing layerremoveFromSuperlayer 不删除层
【发布时间】:2014-05-03 23:01:00
【问题描述】:

我正在编写允许用户临时突出显示图像的一部分的代码。在我的视图类中,我使用了 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?

【问题讨论】:

  • 顺便说一句,这是一个非常恰当的问题(对此表示赞同)。您只展示了所有基本代码,并且您已经完成了大部分日志记录,以便确定正在发生的事情(尽管有一个重要的日志记录您没有做,这将揭示问题的根源)。你的推理清晰简洁,问题本身也很清楚。而且您在发布之前已经完成了作业。会不会所有的问题都是这样的。

标签: ios7 caanimation cashapelayer


【解决方案1】:

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

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

它们的顺序错误!颠倒他们的顺序,一切都会好起来的。

原因:添加到图层后不能修改动画。好吧,你可以,但它没有用:动画已被复制,所以你现在修改的不是你添加的动画。

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

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

- (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

【讨论】:

  • 但是如果您在代码中直接将不透明度设置为 0,您的动画将不会运行(作为动画)。你最终必须解决这个问题。
  • 感谢您的帮助。它现在运行正常。您对不透明度问题也是正确的。我也在其他地方设置了这个,你指出不需要这条线。
猜你喜欢
  • 2015-08-14
  • 2023-02-04
  • 2011-06-13
  • 2017-07-17
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
相关资源
最近更新 更多