Reputation: 279
I am trying to make an animation where two layers move to the side, scale down, and rotate a little bit in 3D, all at the same time (then move back with the layer previously at the bottom not on top). I tried several methods, but none seem to work.
I have the 3d transform animation like so:
perspectiveTransformLeft = CATransform3DIdentity;
perspectiveTransformLeft.m34 = 1.0 / 500;
perspectiveTransformLeft = CATransform3DRotate(perspectiveTransformLeft, 35.0f * M_PI / 360.0f, 0.0f, 1.0f, 0.0f);
I've tried adding a scale transform that didn't work:
perspectiveTransformLeft = CATransform3DMakeScale(0.75, 0.75, 1);
I've tried to scale the layer in an animation block, but that didn't work either:
[UIView animateWithDuration:1.0f
delay:0.0f
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
endingLayer.frame = CGRectMake(20.0f, 0.0f, 724.0f, 538.0f);
switchViewBottom.layer.transform = perspectiveTransformRight;
}
completion:^(BOOL finished){
[delegate switchAnimationFinished];
}
];
I am at a loss. Can someone help me?
Upvotes: 5
Views: 3605
Reputation: 3366
Do some reading on CAAnimationGroup and use CABasicAnimations instead. That should held you achieve what you're after. I'll search for an example in my code (I previously used it) if you'll have issues implementing it.
Edit: Here's some code
typedef void (^animationCompletionBlock)(void);
typedef void (^animationStartedBlock)(void);
- (void)addAnimations:(NSArray *)animations withDuration:(CGFloat)animationDuration onView:(UIView *)aView {
animationStartedBlock startBlock = ^void(void) {
// Additional Animation start code here
};
animationCompletionBlock endBlock = ^void(void) {
// Additional animation completed code here
};
CAAnimationGroup *group = [CAAnimationGroup animation];
group.fillMode = kCAFillModeForwards;
group.removedOnCompletion = NO;
group.duration = animationDuration;
[group setAnimations:animations];
group.delegate = self;
[group setValue:startBlock forKey:@"animationStartedBlock"];
[group setValue:endBlock forKey:@"animationCompletionBlock"];
[aView.layer addAnimation:group forKey:@"yourAnimationName"];
}
This will have your completion blocks called in your delegate
// Animation Delegate
- (void)animationDidStart:(CAAnimation *)anim {
animationStartedBlock animationStartedBlock = [anim valueForKey:@"animationStartedBlock"];
if (animationStartedBlock) {
animationStartedBlock();
}
}
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
animationCompletionBlock animationCompleteBlock = [theAnimation valueForKey:@"animationCompletionBlock"];
if (animationCompleteBlock) {
animationCompleteBlock();
}
}
How you create the animations and add them to an array to pass to this method is up to you, depending on what animations you want.
This is an example for two scale / fade animations:
// Scale
- (CABasicAnimation *)scaleAnimationForImageView:(UIImageView *)imageView withDuration:(CGFloat)duration {
CGRect imageFrame = imageView.frame;
CABasicAnimation *resizeAnimation = [CABasicAnimation animationWithKeyPath:@"bounds.size"];
[resizeAnimation setToValue:[NSValue valueWithCGSize:CGSizeMake(40.0f, imageFrame.size.height * (40.0f / imageFrame.size.width))]];
resizeAnimation.fillMode = kCAFillModeForwards;
resizeAnimation.duration = duration;
resizeAnimation.removedOnCompletion = NO;
return resizeAnimation;
}
// Fade
- (CABasicAnimation *)fadeAnimationWithFinalOpacity:(CGFloat)opacity withDuration:(CGFloat)duration {
CABasicAnimation *fadeOutAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
[fadeOutAnimation setToValue:[NSNumber numberWithFloat:opacity]];
fadeOutAnimation.fillMode = kCAFillModeForwards;
fadeOutAnimation.removedOnCompletion = NO;
fadeOutAnimation.duration = duration;
return fadeOutAnimation;
}
Upvotes: 5