旋转按钮动画不起作用

时间:2016-11-02 09:44:15

标签: ios swift uiview

我有一个按钮,当它被点击时,它应该自行旋转,这是我的代码:

@IBAction func calculateButtonTapped(_ sender: UIButton) {
    let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
    rotateAnimation.fromValue = 0.0
    rotateAnimation.toValue = CGFloat(M_PI)
    rotateAnimation.speed = 3.0
    rotateAnimation.repeatCount = 6000
    calculateButton.layer.add(rotateAnimation, forKey: nil)

    DispatchQueue.main.async {
        self.openCircle(withCenter: sender.center, dataSource: self.calculator!.iterateWPItems())
        self.calculateButton.layer.removeAllAnimations()
    }
}

然而,有时当我点击按钮时,它立即返回到正常状态然后旋转,有时按钮变为暗选择状态,并且根本没有动画,动画完成后的任务。如果我没有停止动画,它会在openCircle完成后启动。

可能是什么原因?

3 个答案:

答案 0 :(得分:0)

  1. 您未设置动画的duration。 替换此
  2. rotateAnimation.speed = 3.0
    

    用这个

    rotateAnimation.duration = 3.0
    
    1.   

      @alexburtnik,可以阻止主线程

    2. 不,它不好。您应该在completion方法中添加openCircle参数,并在动画(或其他)完成时调用它。如果你阻止主线程,你将有一个冻结的UI,强烈建议不要这样做。

      1. 如果您不确定在主线程上调用了calculateButtonTapped,那么您也应该调度方法的第一部分。与UI 相关的所有内容必须在主线程上完成。
      2. 看起来应该类似于:

        @IBAction func calculateButtonTapped(_ sender: UIButton) {
            let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
            rotateAnimation.fromValue = 0.0
            rotateAnimation.toValue = CGFloat(M_PI)
            rotateAnimation.duration = 3.0
            rotateAnimation.repeatCount = .infinity //endless animation
            calculateButton.layer.add(rotateAnimation, forKey: nil)
        
            self.openCircle(
                withCenter: sender.center,
                dataSource: self.calculator!.iterateWPItems(),
                completion: {
                    self.calculateButton.layer.removeAllAnimations()
            })
        }
        
        func openCircle(withCenter: CGPoint, dataSource: DataSourceProtocol, completion: (()->Void)?) {
            //do your staff and call completion when you're finished
            //don't block main thread!
        }
        

答案 1 :(得分:0)

尝试此操作以通过将按钮连接到故事板上的操作来旋转单击的按钮。您当然可以通过传递任何UIButton作为发件人来调用此函数!

@IBAction func calculateButtonTapped(_ sender: UIButton) {

    guard (sender.layer.animation(forKey: "rotate") == nil) else { return }

    let rotationDuration: Float = 3.0

    let animation = CABasicAnimation(keyPath: "transform.rotation")
    animation.toValue = Float.pi * rotationDuration
    animation.duration = CFTimeInterval(rotationDuration)
    animation.repeatCount = .infinity

    sender.layer.add(animation, forKey: "rotate")

}

rotationDuration更改为完整旋转所需的任何时间长度。您还可以进一步调整该函数以将其作为参数。

修改:添加了一条警卫声明,以便每次按下该按钮时轮换都不会累加。

答案 2 :(得分:0)

感谢大家的回答,我在多线程的速成课程后自己找到了解决方案,问题是我用openCircle方法阻止了主线程。

这是更新后的代码:

@IBAction func calculateButtonTapped(_ sender: UIButton) {

    let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
    rotateAnimation.fromValue = 0.0
    rotateAnimation.toValue = CGFloat(M_PI)
    rotateAnimation.speed = 3.0
    rotateAnimation.repeatCount = .infinity

    DispatchQueue.global(qos: .userInitiated).async {
        self.openCircle(withCenter: sender.center, dataSource: self.calculator!.iterateWPItems()){}
        DispatchQueue.main.sync {
            self.calculateButton.layer.removeAllAnimations()
        }
    }
    self.calculateButton.layer.add(rotateAnimation, forKey: nil)
}