Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple CALayer animations Executed at the Same time

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?

like image 894
user1799795 Avatar asked May 22 '13 08:05

user1799795


People also ask

How to run two animations simultaneously in jQuery?

How to run two animations simultaneously in jQuery ? The .animate () method in jQuery is used to handle effects and animations. Properties which have numeric values can be animated by this method such as width, height, border-width etc. however, the property names should be camel cased ( eg. borderWidth).

How to trigger multiple animations at the same time?

We can cause the animations to trigger simultaneously in two ways. By passing the option queue : false, we ensure that the animations do not get added to the queue. The default animation queue in jQuery is called fx.

When does the animate () method trigger in jQuery?

The animate () method will only trigger after the event (being listened to) occurs on the page. For two different HTML elements, on triggering of an event, the animations will occur simultaneously. According the official jQuery documentation, the .animate () method offers two prototypes:

How to add chained animations to a queue in JavaScript?

.animate (properties, options): Both properties and options are plain javascript objects. The options object can be passed with an optional ‘queue’ property which can allow us to choose whether we want the chained animations to be added to the queue or not. We will use the second prototype for the purpose of this example.


1 Answers

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;
}
like image 64
Vlad Avatar answered Oct 04 '22 19:10

Vlad