Search code examples
animationioscore-animation

Core animation: why can I not composite two animations?


I am trying to animate a wheel

When the finger rests for > 0.1s, the wheel ' pops out ' ie I animate Scale from 1.0 to 1.2.

when the finger moves, the wheel rotates with it ( only if it is popped out ).

But I'm getting a problem: as soon as it starts to rotate, the scale reduces back to 1.0.

- (void) spin: (Direction) direction
{
 float thetaOld = thetaWheel;

 float k = (direction == AntiClockwise) ? -1 : 1;
 float t = 2 * M_PI * ( k / 12.0 );
 thetaWheel += t;

 CABasicAnimation * anim = [CABasicAnimation animationWithKeyPath:@"transform"];

 anim.fromValue = [NSNumber numberWithDouble: thetaOld];
 anim.toValue = [NSNumber numberWithDouble: thetaWheel];

 anim.valueFunction = [CAValueFunction functionWithName: kCAValueFunctionRotateZ];

 anim.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; 

 anim.duration = 0.1f;
 anim.fillMode = kCAFillModeForwards;
 anim.removedOnCompletion = NO;

 [self.wheelLayer addAnimation: anim forKey:@"transform"];
}

- (void) popOut
{
 CABasicAnimation * anim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

 anim.fromValue = [NSNumber numberWithDouble: 1.0];
 anim.toValue = [NSNumber numberWithDouble: 1.2];

 anim.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; 

 anim.duration = 0.25f;
 anim.fillMode = kCAFillModeForwards;
 anim.removedOnCompletion = NO;

 [self.wheelLayer addAnimation: anim forKey:@"transform.scale"];
}

// doesnt get used yet
- (void) popBack
{
 CABasicAnimation * anim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

 anim.fromValue = [NSNumber numberWithDouble: 1.2];
 anim.toValue = [NSNumber numberWithDouble: 1.0];

 anim.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; 

 anim.duration = 0.1f;
 anim.fillMode = kCAFillModeForwards;
 anim.removedOnCompletion = NO;

 [self.wheelLayer addAnimation: anim forKey:@"transform.scale"];
}

The last routine is not getting used at this time! So I can't see what is reducing the scale back to 1...

it looks like somehow the second animation is overwriting the first one...

how to do this properly?


Solution

  • I guess (have not tested that) that layer transform applied in animation for 'transform' keyPath overrides transformation you applied in your scaling animation.

    For rotation try using animation with transform.rotation.z keypath instead (and you won't need to set valueFunction in that case)