2011-10-17 39 views
6

如何让一个CABasicAnimation在另一个完成后运行?换句话说,顺序。我已经添加了开始第二动画的时间,但它似乎是第二动画没有得到执行:依次运行CABasicAnimation

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"]; 

任何想法,为什么?

回答

15

更新的代码,这将工作!

1动画

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"]; 

第二动画:

- (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"]; 
} 

}

这是怎样的一个一号完成后的第二个动画会火。

+0

这并不会工作。animationDidStop被无限调用了 – adit

+0

你是否复制了两个代码段?他们不一样。 –

+0

如果你有一个循环,你确定你没有设置第二个动画的委托,这样第二个动画也调用animationDidStop? – isaac

1

最简单的事情是为第一个动画设置一个委托,并在该对象中实现​​。在该方法中,触发第二个动画。

+0

都能跟得上没有工作 – adit

1

您的动画未按计划运行的原因是由于您编码的方式&使用过核心动画。核心动画全部由GPU供电。 CA infact处理一些事情非常好,以最佳方式呈现动画。

它的一个要素是现代显卡的原始并行处理能力,另一个因素是Core Animation可以在卡上缓存CALayer的内容,以便您的代码不需要不断地重绘它。顺便说一下,这是iPhone UI在一些相对适中的硬件上如此快速的原因的一部分。核心动画可以自动利用多核Mac,因为图层树在上呈现为单独的线程

最后一行是imp。 CA的运行在一个单独的线程中(&不是主线程)。所以回到你的问题,你有两个CA的块试图动画相同的transform.translation.y两个在同一时间!这将如何工作?

因此,要解决这个问题,无论是做 -

  1. 什么有人建议,把延迟第二动画,使得第一动画后,仅在第一OS结束后第二次踢。
  2. 或尝试在一个单独的块中完成整个动画(再次按照某人的建议)。

我只是想强调理论&推理核心动画的工作方式。希望这有助于...

0

最简单和最干净的方法是使用CAAnimationGroup。看看这个答案 - 它帮助我。

Chaining Core Animation animations

+3

'CAAnimationGroup'用于并发而非顺序动画,通常用于动画多个属性。 – Barry