Will Ullrich
Will Ullrich

Reputation: 2238

Spin Animation Resets to Original Image

For fun I have been trying to get a lottery wheel type object set up using Xcode in objective c. So far I have been able to successfully spin the object with random rotations, and stopping at 1 of 8 items on the wheel.

The problem is, I am not sure how to "save" the animation layer that is spun. Each time I spin the wheel, once the animation is completed it resets and shows the image in the original orientation. Below is the code I have setup for spinning the wheel. (NOTE: in this code I merely just have a set rotation. this is the template I am working with to try and retain the image. The other code is in a different project that stores the stopping point and corrects it to the center of on of those objects.)

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

#define SPIN_CLOCK_WISE 1
#define SPIN_COUNTERCLOCK_WISE -1

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (IBAction)spinButton:(id)sender {
    [self spinLayer:_spinImage.layer duration:10 direction:SPIN_CLOCK_WISE];

}


- (void)spinLayer:(CALayer *)inLayer duration:(CFTimeInterval)inDuration
        direction:(int)direction
{
    CABasicAnimation* rotationAnimation;

    // Rotate about the z axis
    rotationAnimation =
    [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

    // Rotate 360 degress, in direction specified
    rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 22.3 * direction];

    // Perform the rotation over this many seconds
    rotationAnimation.duration = inDuration;

    // Set the pacing of the animation
    rotationAnimation.timingFunction =
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    // Add animation to the layer and make it so
    [inLayer addAnimation:rotationAnimation forKey:@"rotationAnimation"];

    // Save animation
//%%%%%%%%%%  THIS IS WHERE I AM STUCK!! %%%%%%%%%
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

If someone could just help me retain the spun image so that once the spinLayer method completes, the image stays rotated to the new spin orientation, I would greatly appreciate it. Thanks!

Upvotes: 1

Views: 110

Answers (1)

David Rönnqvist
David Rönnqvist

Reputation: 56635

The confusing part is that the animation is only changing the layers appearance, not the properties of the layer.

You can think of the animation as overriding the property when it's being rendered.

enter image description here

As you can see, since the model value never changed, when the animation has finished and removes itself, the layer goes back to rendering the actual value of that property.

The wrong way to solve this problem would be to keep the animation around forever. It does produce the correct rendering, but has some unwanted side effects since the model value now "permanently" doesn't match the appearance.

enter image description here

Instead, the better solution is to update the value of the property you are animating as you add the animation to the layer. This might feel like it would break the animation, but if the animation is animating from the old value to the new value, it will "override" whatever the model value is why rendered and when the animation removes the end value will match the model value.

enter image description here


For an more in-depth discussion about where to change the model value when adding the animation and about the way animations are applied, see this question and this blog post of mine.

Upvotes: 1

Related Questions