Reputation: 5005
SWIFT - OSX
I have a bunch of imageViews set in my Main.storyboard. I am trying to make them spin when the app starts and i would like them to indefinitely. I came across the roateByAngle(angle: CGFloat), but this doesn't animate it, instead it just jumps to the new angle.
I would like to make two functions, spinClockwise() and spinAntiClockwise() so I can just call them in the viewDidLoad and they will just keep turning.
Ive been playing with CATransform3DMakeRotation but cannot seem to get my desired results
let width = myImg.frame.width / 2
let height = myImg.frame.height / 2
myImg.layer?.transform = CATransform3DMakeRotation(180, width, height, 1)
Let me know if i can be more specific. Thanks
Upvotes: 2
Views: 1795
Reputation: 516
For me, I could not change the anchor point. It was spinning around (0,0) which is bottom left. I moved the anchor point to (0.5, 0.5), but still no luck. Then I came accross with this answer. I modified my code like below, and it begins to rotate around itself. I observed a drawback though, the place of the view somehow shifted, but it can be fixed by trial and error, trying to get it to the right place.
extension NSView {
func startRotating(duration: Double = 1) {
let kAnimationKey = "rotation"
//self.wantsLayer = true
if layer?.animation(forKey: kAnimationKey) == nil {
var oldFrame = self.frame
self.layer?.anchorPoint = CGPoint(x: 1, y: 1)
self.frame = oldFrame
let animate = CABasicAnimation(keyPath: "transform.rotation")
animate.duration = duration
animate.repeatCount = Float.infinity
animate.fromValue = 0.0
animate.toValue = Double.pi * 2.0
self.layer?.add(animate, forKey: kAnimationKey)
oldFrame = self.frame
self.layer?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.frame = oldFrame
}
}
}
Upvotes: 1
Reputation: 457
You could add an extension of UIView or UIImageView like this:
extension UIView {
///The less is the timeToRotate, the more fast the animation is !
func spinClockwise(timeToRotate: Double) {
startRotate(CGFloat(M_PI_2), timeToRotate: timeToRotate)
}
///The less is the timeToRotate, the more fast the animation is !
func spinAntiClockwise(timeToRotate: Double) {
startRotate(CGFloat(-M_PI_2), timeToRotate: timeToRotate)
}
func startRotate(angle: CGFloat, timeToRotate: Double) {
UIView.animateWithDuration(timeToRotate, delay: 0.0, options:[UIViewAnimationOptions.CurveLinear, UIViewAnimationOptions.Repeat], animations: {
self.transform = CGAffineTransformMakeRotation(angle)
}, completion: nil)
print("Start rotating")
}
func stopAnimations() {
self.layer.removeAllAnimations()
print("Stop rotating")
}
}
So when you want to rotate your myImg
, you just have to call:
myImg.spinClockwise(3)
And when you want to stop it:
myImg.stopAnimations()
NOTE: I added a playground just so you can test it out ;)
Cheers!
EDIT:
My bad, Here is the example for NSView:
extension NSView {
///The less is the timeToRotate, the more fast the animation is !
func spinClockwise(timeToRotate: Double) {
startRotate(CGFloat(-1 * M_PI * 2.0), timeToRotate: timeToRotate)
}
///The less is the timeToRotate, the more fast the animation is !
func spinAntiClockwise(timeToRotate: Double) {
startRotate(CGFloat(M_PI * 2.0), timeToRotate: timeToRotate)
}
func startRotate(angle: CGFloat, timeToRotate: Double) {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = 0.0
rotateAnimation.toValue = angle
rotateAnimation.duration = timeToRotate
rotateAnimation.repeatCount = .infinity
self.layer?.addAnimation(rotateAnimation, forKey: nil)
Swift.print("Start rotating")
}
func stopAnimations() {
self.layer?.removeAllAnimations()
Swift.print("Stop rotating")
}
}
Important note: Now, after my tests, I noticed that you must set the anchor point of your NSView in the middle so that it can rotate around its center:
view.layer?.anchorPoint = CGPointMake(0.5, 0.5)
I added a new playground with the OSX example
Upvotes: 2