Search code examples
iosobjective-ccore-plotcabasicanimation

Animation is not working as expected


I implemented corePlot in xcode and I'm using the pie chart. I'm trying to create a 3d flip animation while the chart reloads. Here is the code:

CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"];
scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];
scaleAnimation.toValue = [NSNumber numberWithFloat:0.5];
scaleAnimation.duration = 1.0f;
scaleAnimation.removedOnCompletion = NO;
[self.pieChart addAnimation:scaleAnimation forKey:@"scale"];

[self.pieChart reloadData];

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"];
animation.fromValue = [NSNumber numberWithFloat:0.5];
animation.toValue = [NSNumber numberWithFloat:1.0];
animation.duration = 1.0f;
[self.pieChart addAnimation:animation forKey:@"scale"];

I didn't get desirable effects. I think what's happening is, both animations are happening at once. (Though I'm not sure that is what's happening.)

Also, is it possible to add z-depth? If so, how?

Update

I tried the follwoing:

CABasicAnimation *currentAnition = (CABasicAnimation *)anim;
if (currentAnition == self.scaleAnimation {...}

And it didn't work.


Solution

  • CAAnimation is KVC compliant, so we can store whether you're starting or finishing for lookup in the delegate methods:

    {
        CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"];
        [scaleAnimation setValue:@(YES) forKey:@"scaleAnimation"];
        // set the delegate
        scaleAnimation.delegate = self;
        scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];
        scaleAnimation.toValue = [NSNumber numberWithFloat:0.5];
        scaleAnimation.duration = 1.0f;
        scaleAnimation.removedOnCompletion = NO;
        [self.pieChart addAnimation:scaleAnimation forKey:@"scale"];
        [self.pieChart reloadData];
    }
    
    - (void)runSecondAnimation
    {
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"];
        [animation setValue:@(YES) forKey:@"secondAnimation"];
        animation.delegate = self;
        animation.fromValue = [NSNumber numberWithFloat:0.5];
        animation.toValue = [NSNumber numberWithFloat:1.0];
        animation.duration = 1.0f;
        [self.pieChart addAnimation:animation forKey:@"scale"];
    }
    
    /* Called when the animation either completes its active duration or
     * is removed from the object it is attached to (i.e. the layer). 'flag'
     * is true if the animation reached the end of its active duration
     * without being removed. */
    
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
        BOOL scaleAnimation = [[anim valueForKey:@"scaleAnimation"] boolValue];
        if (scaleAnimation) {
            [self runSecondAnimation];
        }
        BOOL secondAnimation = [[anim valueForKey:@"secondAnimation"] boolValue];
        if (secondAnimation) {
            [self runThirdAnimation];
        }
    }
    

    And remember you have also:

    /* Called when the animation begins its active duration. */
    - (void)animationDidStart:(CAAnimation *)anim;