1

动画化CAShapeLayer时,是否需要不断更新图层路径,还是有办法单独依靠CABasicAnimation?CAShapeLayer动画无需更新路径

在下面的例子中,我设置了四个圆圈路径并绘制它们。 然后我想动画他们消失。然而,动画完成后,它们会回到原来的路径。

int radius = halfWidth-30; //the radius is the distance out from the centre 
    trackActive.path = [UIBezierPath bezierPathWithArcCenter:cicleCenter radius:radius startAngle:degreesToRadians(circleStart) endAngle:degreesToRadians(circleEnd) clockwise:true].CGPath; 
    circleActive.path = [UIBezierPath bezierPathWithArcCenter:cicleCenter radius:radius startAngle:degreesToRadians(circleStart) endAngle:degreesToRadians(circleEnd) clockwise:true].CGPath; 

    radius = halfWidth - 10; 
    trackNew.path = [UIBezierPath bezierPathWithArcCenter:cicleCenter radius:radius startAngle:degreesToRadians(circleStart) endAngle:degreesToRadians(circleEnd) clockwise:true].CGPath; 
    circleNew.path = [UIBezierPath bezierPathWithArcCenter:cicleCenter radius:radius startAngle:degreesToRadians(circleStart) endAngle:degreesToRadians(circleEnd) clockwise:true].CGPath; 

    NSArray * layers = @[trackActive, circleActive, trackNew, circleNew]; 
    for (CAShapeLayer * layer in layers){ 

     [CATransaction begin]; 
     CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
     animation.duration = 1.0f; 
     animation.removedOnCompletion = false; 
     animation.fromValue = @(1.0); 
     animation.toValue = @(0.0); 
     animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
     [layer addAnimation:animation forKey:@"circleAnimation"]; 

     [CATransaction commit]; 
    } 

我明白,我可以添加此设置的新路径:

[CATransaction setCompletionBlock:^{ 

     //set the new path 
     layer.path = [UIBezierPath bezierPathWithArcCenter:cicleCenter radius:radius startAngle:degreesToRadians(circleStart) endAngle:degreesToRadians(arcEnd) clockwise:true].CGPath; 

    }]; 

但希望避免继续有更新的路径,而不是依靠动画层上独占。这可能吗?

类似于:layer.path = animation.path或animation.updatesOriginalPath = true;可能是一厢情愿,不确定。

+1

您可以通过将图层的strokeEnd设置为零来省略弹回效果,因为动画不会修改图层的状态。 – clemens

回答

1

你可以简化您的代码并省略弹簧效果:

[CATransaction begin]; 
[CATransaction setAnimationDuration:1.0]; 
[CATransaction setAnimationTimingFunction: kCAMediaTimingFunctionEaseInEaseOut]; 
layer.strokeEnd = 0.0; 
[CATransaction commit]; 

该事务将为您创建并添加一个隐式动画对象。

0

您可以在动画设置一个标志,使其保持在那里它是在年底开始在它应该这样开始:

[animation setRemovedOnCompletion:NO]; 
[animation setFillMode:kCAFillModeBoth]; 

检查也是这样的回答: What exactly does removedOnCompletion = NO do?

+1

您应该避免在图层上保留动画。稍后移除或替换动画将导致_unexpected_效果。 'addAnimation'前的'layer.strokeEnd = 0.0'会有相同的效果。 – clemens

+0

保持动画的另一个缺点是图层不能反映它的_visible state_。它总是为'strokeEnd'返回1.0,但它显示的值为0.0。 – clemens