I've created my own transition animation between views. I animate two properties, the position and the transform, to provide a cube-like transition between views. The frame uses CABasicAnimation
while the transform uses a "2-stage" CAKeyframeAnimation
. Everything works fine except for one small detail I can't seem to figure out. In my transition I apply a CATransform3DScale
on the middle key frame to create a zoom-in/zoom-out effect. That works fine except the animation looks slightly jerky. It's animating the between the key frames in a linear fashion, and I would like to smooth that out. Now CAKeyframeAnimation
has a way to do that using calculationMode
, but it doesn't seem to work for transforms. I've tried setting it to kCAAnimationCubic
and kCAAnimationCubicPaced
with no effect.
Here is the code that animates one view's transform (a similar block of code animates the other view):
CAKeyframeAnimation *aTransform = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
CATransform3D transform1 = RotateOnX(toView, M_PI_4);
transform1 = CATransform3DScale(transform1, RotationalZoom, RotationalZoom, RotationalZoom);
[aTransform setValues:Array([NSValue valueWithCATransform3D:RotateOnX(toView, M_PI_2)],
[NSValue valueWithCATransform3D:transform1],
[NSValue valueWithCATransform3D:RotateOnX(toView, 0)])];
[toView.layer addAnimation:aTransform forKey:@"transform"];
Note: RotateOnX(UIView *, CGFloat)
is a block that returns a transform for a view rotated on X by the desired Radians.
As you can see I only set a scaling transform on the middle key frame. Also, the rotation of the view is perfectly smooth, it's only the scaling that appears to 'jerk' as it changes direction.
Does anyone have any ideas on how to smooth out the scaling/zooming?
Try the timingFunctions
property. Since you have 3 keyframes, you need 2 timing functions: one for the animation from keyframe 0 to keyframe 1, and another for the animation from keyframe 1 to keyframe 2.
aTransform.timingFunctions = [NSArray arrayWithObjects:
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInOut],
nil];