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