I have a method which translates a view and optionally scales it while translating. I am using animation groups and adding the required animations as needed. Here are the animation cases working perfectly.
- Translation (x or y axis or both) (OK)
- Scaling (OK)
- Translation while scaling (MOSTLY)
However, doing a translation while scaling works only when the starting scalefactor is 1. When the view is already scaled, I notice most of the transition jumping instead of animating, although the end result of scaling and translation is correct.
I am posting part of the code for clarification. The problem occurs only when previousZoomScale
is not 1! I appreciate any directions you can point me to.
-(void)performAnimationForView: (AnimationType)animationType
WithDX: (CGFloat)dx
AndDY: (CGFloat)dy
Scale: (CGFloat)scale
Duration: (CGFloat)duration
{
CABasicAnimation *translateXAnimation = nil, *translateYAnimation = nil, *scaleAnimation = nil;
NSString* animationGroupName;
CGPoint newDxDy;
switch (animationType)
{
case kAnimationTranslateAndScale:
// set animation key
animationGroupName = @"translatescale";
translateXAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
translateXAnimation.repeatCount = 0;
translateXAnimation.autoreverses = NO;
translateXAnimation.removedOnCompletion = NO;
translateXAnimation.fillMode = kCAFillModeForwards;
translateXAnimation.fromValue = [NSNumber numberWithFloat: self.previousDxDy.x]; // previous point we're tranlsating from
translateXAnimation.toValue = [NSNumber numberWithFloat:dx]; // destination point
translateYAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
translateYAnimation.repeatCount = 0;
translateYAnimation.autoreverses = NO;
translateYAnimation.removedOnCompletion = NO;
translateYAnimation.fillMode = kCAFillModeForwards;
translateYAnimation.fromValue = [NSNumber numberWithFloat: self.previousDxDy.y];
translateYAnimation.toValue = [NSNumber numberWithFloat:dy];
newDxDy = CGPointMake(dx, dy);
self.previousDxDy = newDxDy;
// scaling animation
scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.autoreverses = NO;
scaleAnimation.repeatCount = 0;
scaleAnimation.removedOnCompletion = NO;
scaleAnimation.fillMode = kCAFillModeForwards;
scaleAnimation.fromValue = [NSNumber numberWithDouble: self.previousZoomScale]; // initial zoom scale
scaleAnimation.toValue = [NSNumber numberWithDouble:scale]; // target scale
self.previousZoomScale = scale;
break;
}
NSMutableArray* animationArray = [[NSMutableArray alloc] initWithObjects: nil];
if (translateXAnimation != nil)
[animationArray addObject: translateXAnimation];
if (translateYAnimation != nil)
[animationArray addObject: translateYAnimation];
if (scaleAnimation != nil)
[animationArray addObject: scaleAnimation];
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
theGroup.duration = duration;
theGroup.removedOnCompletion = NO;
theGroup.fillMode = kCAFillModeForwards;
theGroup.repeatCount = 0;
theGroup.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear];
theGroup.animations = animationArray;
theGroup.delegate = self;
[theGroup setValue: animationGroupName forKey: @"animationtype"];
[self.backgroundImageView.layer addAnimation: theGroup forKey: animationGroupName];
}