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

Chr*_*ris 11 animation mobile-application ios

所以,我对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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

  1. 检查当前动画是否正在进行中
  2. 如果是这样,请确定当前动画角度的位置,然后
  3. 取消当前并从当前旋转开始新动画到新目标旋转

是否有可能将该行为构建到上述函数中?

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

fou*_*dry 4

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

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

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

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

现在您可以在动画方法中使用此方法,该方法将如下所示:

-(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;

}
Run Code Online (Sandbox Code Playgroud)

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

顺便说一句,我建议您以弧度而不是角度来输入您的方法,这意味着您可以删除那些 57.2958 常数。