无需更新路径的 CAShapeLayer 动画
CAShapeLayer Animation without having to update the path
在给CAShapeLayer做动画的时候,是需要不断的更新layer的路径,还是只能依赖CABasicAnimation?
在下面的示例中,我设置了四个圆形路径并绘制它们。
然后我想将它们动画化以消失。然而,在动画完成后,它们 spring 回到原来的路径。
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;可能是一厢情愿,不确定。
您可以在动画中设置一个标志,使其停留在最后的位置并从应该开始的地方开始,如下所示:
[animation setRemovedOnCompletion:NO];
[animation setFillMode:kCAFillModeBoth];
同时检查这个答案:
What exactly does removedOnCompletion = NO do?
您可以简化代码并省略 spring 效果:
[CATransaction begin];
[CATransaction setAnimationDuration:1.0];
[CATransaction setAnimationTimingFunction: kCAMediaTimingFunctionEaseInEaseOut];
layer.strokeEnd = 0.0;
[CATransaction commit];
事务将为您创建并添加一个隐式动画对象。
在给CAShapeLayer做动画的时候,是需要不断的更新layer的路径,还是只能依赖CABasicAnimation?
在下面的示例中,我设置了四个圆形路径并绘制它们。 然后我想将它们动画化以消失。然而,在动画完成后,它们 spring 回到原来的路径。
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;可能是一厢情愿,不确定。
您可以在动画中设置一个标志,使其停留在最后的位置并从应该开始的地方开始,如下所示:
[animation setRemovedOnCompletion:NO];
[animation setFillMode:kCAFillModeBoth];
同时检查这个答案: What exactly does removedOnCompletion = NO do?
您可以简化代码并省略 spring 效果:
[CATransaction begin];
[CATransaction setAnimationDuration:1.0];
[CATransaction setAnimationTimingFunction: kCAMediaTimingFunctionEaseInEaseOut];
layer.strokeEnd = 0.0;
[CATransaction commit];
事务将为您创建并添加一个隐式动画对象。