在 Swift 中如何使 UIImageView 旋转动画?

41

我试图在Swift中通过动画将UIImageView旋转180度。

    UIView.animateWithDuration(1.0, animations: { () -> Void in
        self.arrowImageView.transform = CGAffineTransformMakeRotation(CGFloat(180 * M_PI))
    }) { (succeed) -> Void in

    }

但是根本没有动画效果。 我想使用animateWithDuration,因为我想在某个时刻将其返回到原始状态,使用CGAffineTransformMakeIdentity

使用UIView动画可以实现。

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1)
    UIView.setAnimationCurve(UIViewAnimationCurve.EaseIn)
    let radians = CGFloat(180 * M_PI / 180)
    arrowImageView.transform = CGAffineTransformMakeRotation(radians)
    UIView.commitAnimations()

请参见以下链接以获取有关此问题的更多信息:https://dev59.com/qmgt5IYBdhLWcg3w-ST1#48838627 - Jack
11个回答

45

======= UIView的扩展 =======

我在互联网上找到了这个答案,测试后发现它完美地工作。希望这对任何人有帮助,只需将UIView更改为您需要的内容,例如UIView、UIButton、UIImageView等,并使用myUIView.rotate()函数访问,在这里myUIView应该用您的视图名称(IBOutlet->名称)替换为具有正确视图类型的扩展。这是我找到这个答案的链接。而且这个方法很容易就能实现!

=== SWIFT 3 / 4 ===

extension UIView{
    func rotate() {
        let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
        rotation.toValue = NSNumber(double: M_PI * 2)
        rotation.duration = 1
        rotation.cumulative = true
        rotation.repeatCount = FLT_MAX
        self.layer.addAnimation(rotation, forKey: "rotationAnimation")
    }
}

建议改进。感谢所有的建议。

=== SWIFT 5 ===

extension UIView{
    func rotate() {
        let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
        rotation.toValue = NSNumber(value: Double.pi * 2)
        rotation.duration = 1
        rotation.isCumulative = true
        rotation.repeatCount = Float.greatestFiniteMagnitude
        self.layer.add(rotation, forKey: "rotationAnimation")
    }
}

然后像下面这样调用该扩展:

self.your_UIViewOutletName_myUIView_here.rotate()

12
在Swift 4中,M_PI已被替换为Double.piFLT_MAX替换为Float.greatestFiniteMagnitude,而cumulative替换为isCumulative :) - Rakshitha Muranga Rodrigo
请注意:此扩展可以移除,仅限于功能使用时进行修改。我创建了这个扩展程序,因为它可以在任何地方重复利用,并且你可以将其用于任何类型的视图,例如 UIImageView、UIView 等等。 - Rakshitha Muranga Rodrigo
你很可能不需要改变被继承的类 - 你提到的这3个类都是从UIView继承而来的,还有许多其他的类也是如此。 - froggomad

26

这里是旋转ImageView的代码。Swift 3.0

UIView.animate(withDuration:2.0, animations: {
            self.dropDownImage.transform = CGAffineTransform(rotationAngle: CGFloat(imageRotation))
        })

18

首先,如果你想要旋转180度,这必须转化为弧度。180度的弧度是pi。360度将是2 * pi180 * pi将使您的动画每秒旋转90次,并最终回到原始方向。

其次,我不确定为什么您的代码不起作用,但我知道下面的代码可以工作:

let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = M_PI
rotationAnimation.duration = 1.0

self.arrowImageView.layer.addAnimation(rotationAnimation, forKey: nil)

18

更新的 Swift 4.0 版本:

    let rotation: CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
    rotation.toValue = Double.pi * 2
    rotation.duration = 0.25 // or however long you want ...
    rotation.isCumulative = true
    rotation.repeatCount = Float.greatestFiniteMagnitude
    yourView.layer.add(rotation, forKey: "rotationAnimation")

14

Swift 5.0

extension UIImageView{
    func rotate() {
        let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
        rotation.toValue = NSNumber(value: Double.pi * 2)
        rotation.duration = 2
        rotation.isCumulative = true
        rotation.repeatCount = Float.greatestFiniteMagnitude
        self.layer.add(rotation, forKey: "rotationAnimation")
    }
}

更新至 @Rakshitha Muranga Rodrigo 的回答。


很好的建议,谢谢。其中一个开发者也在帖子上提出了这个建议,所以我现在也已经包括进去了...干杯! - Rakshitha Muranga Rodrigo

12
你忘记在 CGFloat(180 * M_PI) 上添加 / 180。请尝试使用以下代码:
UIView.animate(withDuration: 1.0) {[weak self] in
    self?.arrowImageView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
}

9

90度旋转

var shouldRotateArrow = false {
    didSet {
        rotateArrow()
    }
}

private func rotateArrow() {
    let angle: CGFloat = shouldRotateArrow ? .pi / 2 : 0
    UIView.animate(withDuration: Constants.arrowRotationDuration) {
        self.arrowImageView.transform = CGAffineTransform(rotationAngle: angle)
    }
}

7

对我来说,最好且最简短的解决方案是(Swift 3/4):

self.YourImageView.transform = showing ? CGAffineTransform(rotationAngle: CGFloat.pi) : CGAffineTransform.identity

"showing"是一个值,用于确定图像是否旋转 - 您可以在此处使用自己的逻辑


7

请确保在主线程中操作

DispatchQueue.main.async {
   UIView.animateWithDuration(1.0, animations: { () -> Void in
     self.arrowImageView.transform = CGAffineTransformMakeRotation(CGFloat(180 * M_PI))
   }) { (succeed) -> Void in

   }
}

0
以下代码有助于连续旋转视图。使用.repeat模式的UIView animate可以无限期地重复动画。
开始旋转ImageView的方法如下: -----------------
func startSpinning()  {
            UIView.animate(withDuration: 0.5, delay: 0, options: .repeat, animations: { () -> Void in
                self.gearImageView!.transform = self.gearImageView!.transform.rotated(by: .pi / 2)
                })
        }




To stop spin ImageView 
--------------------

func stopSpinning()  {
        self.gearImageView.layer.removeAllAnimations()
    }

请不要仅仅发布代码作为答案,还要提供解释您的代码是如何解决问题的。带有解释的答案通常更有帮助和更高质量,并且更有可能吸引赞同。 - Tyler2P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接