开始/停止图像视图旋转动画

问题描述:

我有一个开始/停止按钮和我想要旋转的图像视图。开始/停止图像视图旋转动画

当我按下按钮时,我想要开始旋转,当我再次按下按钮时,图像应该停止旋转。我目前使用的是动画UIView,但我还没有想出停止视图动画的方法。

我想让图像旋转,但是当动画停止时,图像不应该回到起始位置,而是继续动画。

var isTapped = true 

    @IBAction func startStopButtonTapped(_ sender: Any) { 
     ruotate() 
     isTapped = !isTapped 
    } 

    func ruotate() { 
     if isTapped { 
      UIView.animate(withDuration: 5, delay: 0, options: .repeat, animations: {() -> Void in 
      self.imageWood.transform =  self.imageWood.transform.rotated(by: CGFloat(M_PI_2)) 
      }, completion: { finished in 
      ruotate() 
      }) 
    } } 

这是我的代码,但它不像我的方面工作。

+1

您可以使用'CABasicAnimation'来实现开始/停止动画。 –

斯威夫特3.X

开始动画

let rotationAnimation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") 
    rotationAnimation.toValue = NSNumber(value: .pi * 2.0) 
    rotationAnimation.duration = 0.5; 
    rotationAnimation.isCumulative = true; 
    rotationAnimation.repeatCount = .infinity; 
    self.imageWood?.layer.add(rotationAnimation, forKey: "rotationAnimation") 

停止动画

self.imageWood?.layer.removeAnimation(forKey: "rotationAnimation") 

斯威夫特2.x的

开始动画

let rotationAnimation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") 
    rotationAnimation.toValue = NSNumber(double: M_PI * 2.0) 
    rotationAnimation.duration = 1; 
    rotationAnimation.cumulative = true; 
    rotationAnimation.repeatCount = .infinity; 
    self.imageWood?.layer.addAnimation(rotationAnimation, forKey: "rotationAnimation") 

停止动画

self.imageWood?.layer.removeAnimation(forKey: "rotationAnimation") 
+2

这会按照你说的停止动画,但该图层会捕捉到它的最终位置。如果您希望在当前状态下停止动画,则需要采取额外的步骤:一种方法是从表示层获取图层变换,在实际图层上设置变形,然后删除动画。另一种选择是将动画的动画速度设置为零。 –

+0

@DuncanC感谢您的建议,同时我邀请您以另一种方式编辑答案.. !! –

+0

我刚刚发布了一个备用解决方案的答案。 –

你的代码,使图像旋转的2PI的角度,但如果你点击按钮的同时旋转不会结束,动画将在停止之前完成,这就是为什么它会进入初始位置。

您应该使用CABasicAnimation来使用旋转,您可以随时停止保持最后的位置。使用

现有的代码就可以实现它通过以下方式

var isTapped = true 

@IBAction func startStopButtonTapped(_ sender: Any) { 
    ruotate() 
    isTapped = !isTapped 
} 

func ruotate() { 
    if isTapped { 
     let rotationAnimation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z") 
     rotationAnimation.toValue = NSNumber(value: Double.pi * 2.0) 
     rotationAnimation.duration = 1; 
     rotationAnimation.isCumulative = true; 
     rotationAnimation.repeatCount = HUGE; 
     self.imageWood?.layer.add(rotationAnimation, forKey: "rotationAnimation") 
    }else{ 
     self.imageWood?.layer.removeAnimation(forKey: "rotationAnimation") 
    } 
} 

苹果增加了一个新的类,UIViewPropertyAnimator,到iOS 10. UIViewPropertyAnimator让您轻松创建可暂停基于的UIView的动画,扭转,并来回擦洗。

如果您重构代码以使用A UIViewPropertyAnimator,则应该可以暂停和恢复动画。

我有一个sample project on Github演示使用UIViewPropertyAnimator。我建议看看这个。

+0

谢谢邓肯。我期待支持iOS 9+,因此可能是目前的第二种选择。 –

+0

另外,我发现你的图书馆虽然相当了不起,但有点复杂以适应我的项目。我不知道我会将旋转逻辑实现到视图控制器中。我明白有一个'viewAnimator',但并不是每个东西都会起作用。 –

+0

看到我的第二个答案。这表明如何停止动画并使其冻结在当前状态。 –

如果您使用UIView动画,操作系统仍会创建一个或多个CAAnimation对象。因此,为了阻止一个UIView动画,你仍然可以使用:

myView.layer.removeAllAnimations() 

或者,如果您创建一个使用一个层上的CAAnimation动画:

myLayer.removeAllAnimations() 

在这两种情况下,你可以捕捉的当前状态动画并将其设置为删除动画之前的最终状态。如果你在一个视图做动画的变换,就像在这个问题上,该代码可能是这样的:

func stopAnimationForView(_ myView: UIView) { 

    //Get the current transform from the layer's presentation layer 
    //(The presentation layer has the state of the "in flight" animation) 
    let transform = myView.layer.presentationLayer.transform 

    //Set the layer's transform to the current state of the transform 
    //from the "in-flight" animation 
    myView.layer.transform = transform 

    //Now remove the animation 
    //and the view's layer will keep the current rotation 
    myView.layer.removeAllAnimations() 
} 

如果你动画以外的变换你需要更改代码的属性以上。