2

I'm having an animation that it supposed to rotate an image constantly. But there are couple issues with it. The velocity is quite odd and despite I've set it to repeat constantly, you can see how it starts, stops and then repeats. Which should not happen. It should be uninterrupted rotating. Also, the other problem is when the animation stops, the image moves left for some reason.

Here's my code:

func animateLogo()
{
    UIView.animate(withDuration: 6.0, delay: 0.0, options: .repeat, animations: {
        self.logo.transform = CGAffineTransform(rotationAngle: ((180.0 * CGFloat(Double.pi)) / 180.0))
    }, completion: nil)
}
Dani
  • 3,427
  • 3
  • 28
  • 54

3 Answers3

7

Try this

func rotateView(targetView: UIView, duration: Double = 1.0) {
    UIView.animate(withDuration: duration, delay: 0.0, options: .curveLinear, animations: {
        targetView.transform = targetView.transform.rotated(by: CGFloat(M_PI))
    }) { finished in
        self.rotateView(targetView: YOUR_LOGO, duration: duration)
    }
}

How to use

self.rotateView(targetView: YOUR_LOGO, duration: duration)
Kamlesh Shingarakhiya
  • 2,757
  • 2
  • 16
  • 34
1

In iOS, the coordinate system is flipped. So you go clockwise as your degree gains. It means that passing 270° will give you an angle, equivalent to 90° in the standard coordinate system. Keep that in mind and provide needed angle accordingly.

Consider the following approach.

1) Handy extension for angle

postfix operator °

protocol IntegerInitializable: ExpressibleByIntegerLiteral {
    init (_: Int)
}

extension Int: IntegerInitializable {
    postfix public static func °(lhs: Int) -> CGFloat {
        return CGFloat(lhs) * .pi / 180
    }
}

extension CGFloat: IntegerInitializable {
    postfix public static func °(lhs: CGFloat) -> CGFloat {
        return lhs * .pi / 180
    }
}

2) Rotate to any angle with CABasicAnimation:

extension UIView {
    func rotateWithAnimation(angle: CGFloat, duration: CGFloat? = nil) {
        let pathAnimation = CABasicAnimation(keyPath: "transform.rotation")
        pathAnimation.duration = CFTimeInterval(duration ?? 2.0)
        pathAnimation.fromValue = 0
        pathAnimation.toValue = angle
        pathAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        self.transform = transform.rotated(by: angle)
        self.layer.add(pathAnimation, forKey: "transform.rotation")
    }
}

Usage:

override func viewDidAppear(_ animated: Bool) {
    // clockwise
    myView.rotateWithAnimation(angle: 90°)

    // counter-clockwise
    myView.rotateWithAnimation(angle: -270°) 

}

Passing negative value will rotate counter-clockwise.

Rashed
  • 2,349
  • 11
  • 26
1

Angles should be in radians and not degrees. Angle in radians = degrees * pi / 180. So if you want to rotate by 360 degrees you should enter radians = 360 * pi / 180 = 2 * pi = 2 * 3.1415 = 6.283.