10

我怎样才能让一个 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"];

知道为什么吗?

4

4 回答 4

15

更新的代码,这将工作!

第一部动画

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

}

这是第一个动画完成后第二个动画的触发方式。

于 2011-10-17T01:27:27.267 回答
1

最简单的做法是为第一个动画设置一个委托并在该对象中实现-animationDidStop:finished:。在该方法中,触发第二个动画。

于 2011-10-17T00:24:46.263 回答
1

您的动画未按计划运行的原因是您编写和使用 Core Animation 的方式。核心动画全部由 GPU 驱动。CA 实际上可以很好地处理几件事以最佳地渲染动画。

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

最后一行是小鬼。CA 在一个单独的线程中运行(而不是主线程)。所以回到你的问题,你有 2 个 CA 块,每个块都试图同时为相同transform.translation.y的两者设置动画!这将如何工作?

所以要解决这个问题,要么 -

  1. 有人建议,延迟第二个动画,以便在第一个动画之后,第二个仅在第一个 os 结束后才开始。
  2. 或尝试在一个块中完成整个动画(再次按照某人的建议)。

我只是想强调核心动画工作方式背后的理论和推理。希望这可以帮助...

于 2011-10-17T02:56:21.597 回答
-1

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

链接核心动画动画

于 2013-06-18T17:34:07.760 回答