如何重置/重新启动动画并让它看起来连续?

时间:2015-06-13 16:37:56

标签: ios animation mobile-application

所以,我对iOS编程很新,并继承了一位前同事的项目。我们正在构建一个包含规范UI的应用程序。当数据进入时,我们希望将“层”(即针图像)从当前角度平滑地旋转到新的目标角度。这就是我们所拥有的,它与慢速数据配合良好:

-(void) MoveNeedleToAngle:(float) target
{
   static float old_Value = 0.0;
   CABasicAnimation *rotateCurrentPressureTick = [CABasicAnimation animationWithKeyPath:@"transform.rotation");
   [rotateCurrentPressureTick setDelegate:self];
   rotateCurrentPressureTick.fromValue = [NSSNumber numberWithFloat:old_value/57.2958];
   rotateCurrentPressureTick.removedOnCompletion=NO;
   rotateCurrentPressureTick.fillMode=kCAFillModeForwards;
   rotateCurrentPressureTick.toValue=[NSSNumber numberWithFloat:target/57.2958];
   rotateCurrentPressureTick.duration=3; // constant 3 second sweep

   [imageView_Needle.layer addAnimation:rotateCurrentPressureTick forKey:@"rotateTick"];
   old_Value = target;
}

问题是我们有一个新的数据方案,在动画完成之前,新数据可以更快地进入(以及上面调用的方法)。发生了什么我认为动画是从旧目标重新启动到新目标,这使它非常跳跃。

所以我想知道如何修改上面的函数来添加连续/可重启的行为,如下所示:

  1. 检查当前动画是否正在进行中
  2. 如果是,请确定当前动画角度的位置,然后
  3. 取消当前并从当前旋转开始新动画到新目标旋转
  4. 是否可以将该行为构建到上述函数中?

    感谢。对不起,如果问题似乎不明,我已经研究并理解了上述对象/方法,但我不是专家。

2 个答案:

答案 0 :(得分:4)

是的,你可以使用现有的方法做到这一点,如果你添加这一点魔力:

    - (void)removeAnimationsFromView:(UIView*)view {
        CALayer *layer = view.layer.presentationLayer;
        CGAffineTransform transform = layer.affineTransform;
        [layer removeAllAnimations];
        view.transform = transform;
    }

表示层封装了动画的实际状态。视图本身不携带动画状态属性,基本上在设置动画结束状态时,视图会在您触发动画时立即获取该状态。它是您在动画期间“看到”的表示层。

此方法在您取消动画的确切时刻捕获表示层的状态,然后将该状态应用于视图。

现在你可以在动画方法中使用这个方法,它看起来像这样:

-(void) MoveNeedleToAngle:(float) target{
    [self removeAnimationsFromView:imageView_Needle];
    id rotation = [imageView_Needle valueForKeyPath:@"layer.transform.rotation.z"];
    CGFloat old_value = [rotation floatValue]*57.2958;

   // static float old_value = 0.0;
    CABasicAnimation *rotateCurrentPressureTick = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    [rotateCurrentPressureTick setDelegate:self];
    rotateCurrentPressureTick.fromValue = [NSNumber numberWithFloat:old_value/57.2958];
    rotateCurrentPressureTick.removedOnCompletion=NO;
    rotateCurrentPressureTick.fillMode=kCAFillModeForwards;
    rotateCurrentPressureTick.toValue=[NSNumber numberWithFloat:target/57.2958];
    rotateCurrentPressureTick.duration=3; // constant 3 second sweep

    [imageView_Needle.layer addAnimation:rotateCurrentPressureTick forKey:@"rotateTick"];

    old_value = target;

}

(我对你的方法做了很少的改动:我也会做一些编码风格改变,但它们与你的问题无关)

顺便说一下,我建议你用弧度而不是度数来提供你的方法,这意味着你可以删除那些57.2958常数。

答案 1 :(得分:1)

您可以从表示层获取当前旋转,只需设置toValue角度即可。无需保留old_value

while

我找到的另一种方法(上面的注释行)不是使用fromValue而是使用toValue来设置图层变换。这将生成相同的动画,但presentationLayer和模型将同步。