排队 CAAnimations 时出现故障

Glitches when queuing CAAnimations

我有一个 CAShapeLayer,我在其中设置了一个圆圈的动画。动画是先"undraw"顺时针画圆,然后顺时针重新画圆。有点像 "rotating circle"。另一种说法:将路径笔画终点移动到起点,然后将起点移动到终点。

动画本身可以运行,但时不时会产生故障。当它应该是 "undrawn".

时,它会在整个圆圈的短暂一瞥中显现出来

为什么会发生这种情况,如何解决?

谢谢,

// Shape creation
layer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, self.width - 2 * OUTER_BORDER_WIDTH, self.width - 2* OUTER_BORDER_WIDTH)].CGPath;

// Animation queuing
-(void) applyNextAnimation
{

    CABasicAnimation* animation;

    if (self.animatingOpening)
    {
        animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        animation.fromValue = [NSNumber numberWithFloat:0.0f];
        animation.toValue = [NSNumber numberWithFloat:1.0f];
        self.animatingOpening = NO;
    }
    else
    {
    animation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
        animation.fromValue = [NSNumber numberWithFloat:0.0f];
        animation.toValue = [NSNumber numberWithFloat:1.0f];
        self.animatingOpening = YES;
    }

    animation.duration = 1.0f;
    animation.autoreverses = NO;
    animation.delegate = self;
    animation.removedOnCompletion = YES;
    [self.outerCircleLayer addAnimation:animation forKey:@"stroke"];
}

// Animation stop callback
-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    if (self.isAnimating)
    {
        [self applyNextAnimation];
    }
}

闪烁是因为你没有在图层上设置对应的属性。因此,当动画完成时,层的模型仍处于动画前的状态,这就是您在两个动画之间瞬间看到的状态。

这会让你走向你想要的...

if (self.animatingOpening)
{

    self.outerCircleLayer.strokeStart = 0.0;

    animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.fromValue = [NSNumber numberWithFloat:0.0f];
    animation.toValue = [NSNumber numberWithFloat:1.0f];
    self.animatingOpening = NO;
}
else
{
    self.outerCircleLayer.strokeStart = 1.0;

    animation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
    animation.fromValue = [NSNumber numberWithFloat:0.0f];
    animation.toValue = [NSNumber numberWithFloat:1.0f];
    self.animatingOpening = YES;
}

animation.duration = 1.0f;
animation.autoreverses = NO;

这几乎可以工作,但是当您从未绘制状态过渡到开始动画绘制状态时,您会注意到一个更细微的故障。圆圈开始时有一个小的反向动画。这是通过将 strokeStart 从 1.0 设置为 0.0 触发的隐式动画:您需要摆脱它,以便所有动画效果都在您的控制之下。您可以最简单地通过在 CATransaction:

上将 disableActions 设置为 YES 来实现这一点
[CATransaction setDisableActions:YES];

(在if (self.animatingOpening)上方添加)