How to make image spin (animation)

2019-05-23 03:11发布

I have an image which is a square and I know how to make it spin. But not sure how to make it spin exactly like this animation here:

enter image description here

Notice how it spins... then stops a little... then spins again... and so on.

What I have just is a basic spin but doesn't look like the gif above:

extension UIView {
    func rotate360Degrees(duration: CFTimeInterval = 3) {
        let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
        rotateAnimation.fromValue = 0.0
        rotateAnimation.toValue = CGFloat(M_PI * 2)
        rotateAnimation.isRemovedOnCompletion = false
        rotateAnimation.duration = duration
        rotateAnimation.repeatCount=Float.infinity
        self.layer.add(rotateAnimation, forKey: nil)
    }
}

Any thoughts on how this is done?

2条回答
不美不萌又怎样
2楼-- · 2019-05-23 04:00

Similar effect can also be achieved with a repeated animation with a delay.

UIView.animate(withDuration: 1,
                      delay: 0.2,
                    options: [.repeat],
                 animations: { imageView.transform = imageView.transform.rotated(by: CGFloat.pi) },
                 completion: nil)
查看更多
狗以群分
3楼-- · 2019-05-23 04:13

You need to use a timing function that accelerates and decelerates, also known as an ease-in-ease-out timing function.

I've modified your function to use Core Animation's standard ease-in-ease-out timing function:

extension UIView {
    func rotate360Degrees(duration: CFTimeInterval = 0.8) {
        let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
        rotateAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        let radians = CGFloat.pi / 4
        rotateAnimation.fromValue = radians
        rotateAnimation.toValue = radians + .pi
        rotateAnimation.isRemovedOnCompletion = false
        rotateAnimation.duration = duration
        rotateAnimation.repeatCount=Float.infinity
        self.layer.add(rotateAnimation, forKey: nil)
    }
}

Result:

demo

Note that in your image, it looks like the box pauses every 180 degrees, so I've changed the function to rotate by only 180 degrees. Since the box has 90 degree radial symmetry, it still looks like it goes all the way around, with pauses at 180 and 360 degrees.

If you need to animate an image without any radial symmetry, you'll need to use a CAKeyframeAnimation to achieve the ease-in-ease-out at both 180 and 360 degrees.

查看更多
登录 后发表回答