Search code examples
iphoneobjective-cipadcore-animation

crossfade animation between two UIImages in objective-c doesn't fade out the first UIImage


I want to crossfade between two different UIImages but for a reason i cannot figure out my first UIImage stays when the second one fades in. Here is the sourcecode of my animation (it does a lot more than just crossfading, but the crossfading is my only problem right now). I need all of the three animations listed below to be executed at the same time.

CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL,startPoint.x, startPoint.y);
CGPathAddLineToPoint(thePath, NULL, endPoint.x, endPoint.y);

CAKeyframeAnimation *positionAnimation =[CAKeyframeAnimation animationWithKeyPath:@"position"];
positionAnimation.path=thePath;
positionAnimation.duration=ti_duration;
positionAnimation.repeatCount=0;
positionAnimation.delegate = self;
positionAnimation.autoreverses=NO;
positionAnimation.fillMode=kCAFillModeForwards;
positionAnimation.removedOnCompletion = NO;
[self.layer addAnimation:positionAnimation forKey:s_direction];

CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:@"contents"];
crossFade.duration = ti_duration;
crossFade.fromValue = (id)img_startImage.CGImage;
crossFade.toValue = (id)img_transferImage.CGImage;
[self.iv_image.layer addAnimation:crossFade forKey:@"animateContentsToTransferState"];
[self.iv_image setImage:img_transferImage];

CAAnimationGroup *theGroup = [CAAnimationGroup animation];
theGroup.duration = ti_duration;
theGroup.repeatCount = 0;
theGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
theGroup.animations = [NSArray arrayWithObjects:/*positionAnimation,*/ crossFade, nil]; // you can add more

[self.layer addAnimation:theGroup forKey:@"move"];

[UIView beginAnimations:@"changeSize" context:nil];
[UIView setAnimationDuration:duration];
self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.transferSize.width, self.transferSize.height);
[UIView commitAnimations];

The animation method containing this sourcecode is in a subclass of UIView. This subclass contains several UIImages and one UIImageView where the image to be displayed is contained in.

Have i forgotten some essential thing or why is my first image not fading away? Can it be because it is animated from some other animation at the same time?

I hope someone can help me with this.

Greets Maverick


Solution

  • Think of CAAnimations as operations applied to the CALayer. The animations current state do not change the layers original contents.

    When the original state seems to snap back at the end of the animation it is actually just the animations operation being removed, and the real layers state is being revealed again.

    What you need to do is to register a delegate for your animation, and change the actual self.layer.contents when the animation ends.

    First:

    crossFade.delegate = self;
    

    Then implement:

    - (void)animationDidStop:(CABasicAnimation *)animation finished:(BOOL)flag {
        self.layer.contents = animation.toValue;
    }