UIView animation not smooth, jerky on repeat

1.5k Views Asked by At

I'm trying to create a rotating-wheel animation and while it's working, the animation seems really jerky. I need to rotate this wheel indefinitely and stop it based on user interaction. The code I've used is given below.

-(void) spinWheel{
    [UIView animateWithDuration:0.1 delay:0 options: UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction animations:^{
        _wheel.transform = CGAffineTransformRotate(_wheel.transform, _rotationVelocity*ONE_SECTION_ROTATION);
    } completion:^(BOOL finished) {
        if(finished){
            if(!_decelerating){
                [self spinWheel];
            }
        }
    }];
}

Now. however, due to the high speed of the spinning of the wheel, there's a jerk noticed when the animation cycle finishes, before the recursive call to restart the animation.

I'm not sure how I would implement something like this to run smoothly.

EDIT: To make things more obvious, _decelerating is ALWAYS false. It is meant to turn _true when a user taps a button, but I have not programmed that in yet. So, the recursive call is always made for now.

3

There are 3 best solutions below

0
On BEST ANSWER

To solve this problem, I used a CABasicAnimation as suggested by vats. I set a fromValue of 0, toValue of one complete rotation, repeatCount of INFINITY, and duration to be equal to the time necessary to complete one rotation.

This allowed me to infinitely rotate the wheel. When I needed it to stop based on the user interaction, I then removed the above animation, calculated the current position of the wheel and replaced with a second animation responsible for deceleration. This second animation was a CAKeyframeAnimation with multiple distinct keyTimes and values based on the speed of deceleration I wanted to set. I've released the code as a gist on github, it's a little messy because a lot of the variable names are specific to my program. But it could give you an idea on how I solved it.

https://gist.github.com/sosale151/454baadd2634590bffbf11a5077b8a7c

0
On

try this :

 -(void) spinWheel {
[UIView animateWithDuration:0.30 animations:^{
_wheel.transform = CGAffineTransformRotate(_wheel.transform, _rotationVelocity*ONE_SECTION_ROTATION);
} completion:^(BOOL finished) {
    if(finished){
        if(!_decelerating){
            [self spinWheel];
        }
    }
}];
}
7
On

With any Transformation(Scaling, rotation, and translation ) it is best considered to use CABasicAnimation instead of UIView animation.

To answer why:

All I know is Quartz provides functions to create and transform objects so that is why CABasicAnimation(Core animation) is worth the deal.