How can I have one CABasicAnimation to run after the other one has finishes? In other words sequentially. I've added the begin time of the second animation, however it seems that the second animation doesn't gets executed:
CABasicAnimation * appearance =[CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
appearance.duration = 0.5;
appearance.fromValue = [NSNumber numberWithFloat:0];
appearance.toValue = [NSNumber numberWithFloat:340];
appearance.repeatCount = 1;
appearance.fillMode = kCAFillModeForwards;
appearance.removedOnCompletion = NO;
[notif.layer addAnimation:appearance forKey:@"transform.translation.y"];
CABasicAnimation * theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
theAnimation.duration = 0.5;
theAnimation.fromValue = [NSNumber numberWithFloat:0];
theAnimation.toValue = [NSNumber numberWithFloat:10];
theAnimation.repeatCount = 3;
theAnimation.autoreverses = YES;
theAnimation.fillMode = kCAFillModeForwards;
theAnimation.removedOnCompletion = NO;
theAnimation.beginTime = appearance.beginTime + appearance.duration;
[notif.layer addAnimation:theAnimation forKey:@"transform.translation.y"];
Any idea why?
Updated Code, this will work!
1st animation
CABasicAnimation * appearance =[CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
[appearance setValue:@"animation1" forKey:@"id"];
appearance.delegate = self;
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:)];
appearance.duration = 0.5;
appearance.fromValue = [NSNumber numberWithFloat:0];
appearance.toValue = [NSNumber numberWithFloat:340];
appearance.repeatCount = 1;
appearance.fillMode = kCAFillModeForwards;
appearance.removedOnCompletion = NO;
[notif.layer addAnimation:appearance forKey:@"transform.translation.y"];
2nd Animation:
- (void)animationDidStop:(CAAnimation *)theAnimation2 finished:(BOOL)flag {
if([[theAnimation2 valueForKey:@"id"] isEqual:@"animation1"]) {
CABasicAnimation * theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
theAnimation.duration = 0.5;
theAnimation.fromValue = [NSNumber numberWithFloat:0];
theAnimation.toValue = [NSNumber numberWithFloat:10];
theAnimation.repeatCount = 3;
theAnimation.autoreverses = YES;
theAnimation.fillMode = kCAFillModeForwards;
theAnimation.removedOnCompletion = NO;
theAnimation.beginTime = appearance.beginTime + appearance.duration;
[notif.layer addAnimation:theAnimation forKey:@"transform.translation.y"];
}
}
This is how the 2nd animation would fire after the 1st one finishes.
The simplest thing to do is set up a delegate for the first animation and in that object implement -animationDidStop:finished:
. In that method, touch off the second animation.
The reason your animation in not running according to plan is due to the way you have coded up & used Core Animation. Core animations are all GPU powered. CA infact handles couple of things very well to render animations optimally.
One element of it is the raw parallel processing power of modern graphics cards, and another is the fact that Core Animation can cache the contents of a CALayer on the card so that your code doesn't need to constantly redraw it. This, by the way, is part of the reason the iPhone UI is so incredibly fast on some relatively modest hardware. Core Animation can automatically take advantage of a multi-core Mac because the layer tree is rendered on a separate thread.
The last line is imp. CA's are running in a separate thread ( & not the main thread). So coming back to your problem, you have 2 blocks of CA's each trying to animate same transform.translation.y
Both at the same time! How would this work?
So to solve this, either do -
I just wanted to highlight the theory & reasoning behind the way Core Animation works. Hope this helps...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With