平滑地旋转刷新按钮图像,使其完成到最近的转弯iOS

时间:2014-06-05 11:15:15

标签: ios ios7 cgaffinetransform cabasicanimation

我正在尝试为刷新按钮设置动画,使其旋转,表示正在进行刷新。它需要是平滑的,因此如果刷新只需要0.1秒,我们仍然可以完成一个完整的旋转,这样用户就可以确认发生的事情并且平稳过渡。它也应该继续旋转直到我停止它,但停止不应该突然停止它只告诉它完成当前转弯。

最初我做了类似的事情

CABasicAnimation *rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2.0 * 10];
rotationAnimation.cumulative = YES;
rotationAnimation.duration = 10;
[self.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];

然后停下来

[self.layer removeAllAnimations];

这在动画持续超过2pi弧度的意义上工作得很好,但是当刷新时间不到1/10时它不会看起来非常平滑,因为动画会得到10%的回合然后突然停止,removeAllAnimations方法将图像重置为默认值。

我设法绕过这个替代停止方法

    CALayer *presentLayer = self.layer.presentationLayer;
    float currentAngle = [(NSNumber *) [presentLayer valueForKeyPath:@"transform.rotation.z"] floatValue];

    [self.layer removeAllAnimations];   

    if (currentAngle < 0) {
        currentAngle = 2 * ABS(currentAngle);
    }

    float rotationProgressPercent = currentAngle / (2 * M_PI);    
    CABasicAnimation *rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimation.fromValue = [NSNumber numberWithFloat:currentAngle];
    rotationAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2];
    rotationAnimation.cumulative = YES;
    rotationAnimation.duration = 1 - rotationProgressPercent;

基本上我以弧度为单位获得旋转的当前角度,停止动画并从该位置开始新动画到两个pi。我必须在持续时间内做一些工作以保持速度不变,速度方面工作正常,但问题是某些动画有一个非常轻微的滞后/抽搐。我相信这是因为停止动画是异步地将此请求发布到系统(这只是推测),并且当我去做第二个动画时,我当前的角度是陈旧的。

我可以尝试其他方法。

1 个答案:

答案 0 :(得分:2)

所以我最终找到了一个解决方案,这是多么有用

-(void)startSpinning {
    if (animating) {
        return;
    }
    animating = YES;
    [self rotateViewWithDuration:1 byAngle:M_PI * 2];

}

- (void)stopSpinning {
    animating = NO;
}


- (void)rotateViewWithDuration:(CFTimeInterval)duration byAngle:(CGFloat)angle {


    [CATransaction begin];
    CABasicAnimation *rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimation.byValue = [NSNumber numberWithFloat:angle];
    rotationAnimation.duration = duration;
    rotationAnimation.removedOnCompletion = YES;

    [CATransaction setCompletionBlock:^{

        if (animating) {
            [self rotateViewWithDuration:duration byAngle:angle];
        }
    }];

    [self.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
    [CATransaction commit];
}