Running CABasicAnimation sequentially

How can I start one CABasicAnimation to start after completing another? In other words, sequentially. I added the start time of the second animation, however it seems that the second animation is not running:

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?

+6
source share
4 answers

Updated code, it 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"]; 

Second 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 will trigger the second animation after the completion of the first.

+15
source

The simplest task is to create a delegate for the first animation and implement this -animationDidStop:finished: object. In this method, tap the second animation.

+1
source

The reason your animation doesnโ€™t work as planned is due to the way you encoded and used Core Animation. The main animations are all GPUs. CA infact handles a couple of things very well to optimize the animation.

One element of this is the raw parallel processing power of modern graphics cards, and the other is that Core Animation can cache the contents of CALayer on the map so that your code does not need to be constantly redrawn. 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 use a multi-core Mac because the layer tree is displayed on a separate stream .

The last line is imp. CAs operate in a separate thread (and not in the main thread). Therefore, returning to your problem, you have 2 CA blocks, each of which is trying to animate the same transform.translation.y Both at the same time! How it works?

To solve this problem, either do -

  • What someone suggested put a delay for the second animation, so that after the first animations, the second kicks only after the first completion.
  • or try to make the whole animation in one block (again, as someone suggested).

I just wanted to emphasize the theory and reasoning about how Core Animation works. Hope this helps ...

+1
source

The easiest and cleanest way is to use the CAAnimationGroup . Take a look at this answer - it helped me.

Animation Kernel Animation Chains

0
source

Source: https://habr.com/ru/post/899425/


All Articles