I'm trying to rotate a UIImageView
360 degrees, and have looked at several tutorials online. I could get none of them working, without the UIView
either stopping, or jumping to a new position.
The latest thing I've tried is:
[UIView animateWithDuration:1.0
delay:0.0
options:0
animations:^{
imageToMove.transform = CGAffineTransformMakeRotation(M_PI);
}
completion:^(BOOL finished){
NSLog(@"Done!");
}];
But if I use 2*pi, it doesn't move at all (since it's the same position). If I try to do just pi (180 degrees), it works, but if I call the method again, it rotates backwards.
EDIT:
[UIView animateWithDuration:1.0
delay:0.0
options:0
animations:^{
[UIView setAnimationRepeatCount:HUGE_VALF];
[UIView setAnimationBeginsFromCurrentState:YES];
imageToMove.transform = CGAffineTransformMakeRotation(M_PI);
}
completion:^(BOOL finished){
NSLog(@"Done!");
}];
doesn't work either. It goes to 180
degrees, pauses for a split second, then resets back to 0
degrees before it starts again.
Found a method (I modified it a bit) that worked perfectly for me: iphone UIImageView rotation
#import <QuartzCore/QuartzCore.h>
- (void) runSpinAnimationOnView:(UIView*)view duration:(CGFloat)duration rotations:(CGFloat)rotations repeat:(float)repeat {
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * rotations * duration ];
rotationAnimation.duration = duration;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = repeat ? HUGE_VALF : 0;
[view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}
Kudos to Richard J. Ross III for the idea, but I found that his code wasn't quite what I needed. The default for options
, I believe, is to give you UIViewAnimationOptionCurveEaseInOut
, which doesn't look right in a continuous animation. Also, I added a check so that I could stop my animation at an even quarter turn if I needed (not infinite, but of indefinite duration), and made the acceleration ramp up during the first 90 degrees, and decelerate during the last 90 degrees (after a stop has been requested):
// an ivar for your class:
BOOL animating;
- (void)spinWithOptions:(UIViewAnimationOptions)options {
// this spin completes 360 degrees every 2 seconds
[UIView animateWithDuration:0.5
delay:0
options:options
animations:^{
self.imageToMove.transform = CGAffineTransformRotate(imageToMove.transform, M_PI / 2);
}
completion:^(BOOL finished) {
if (finished) {
if (animating) {
// if flag still set, keep spinning with constant speed
[self spinWithOptions: UIViewAnimationOptionCurveLinear];
} else if (options != UIViewAnimationOptionCurveEaseOut) {
// one last spin, with deceleration
[self spinWithOptions: UIViewAnimationOptionCurveEaseOut];
}
}
}];
}
- (void)startSpin {
if (!animating) {
animating = YES;
[self spinWithOptions: UIViewAnimationOptionCurveEaseIn];
}
}
- (void)stopSpin {
// set the flag to stop spinning after one last 90 degree increment
animating = NO;
}
I added the ability to handle requests to start spinning again (startSpin
), while the previous spin is winding down (completing). Sample project here on Github.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With