如何在三个不同的对象上链接同一属性的一系列动画?

时间:2012-04-18 04:49:40

标签: ios core-animation

我一直在尝试创建一系列动画,按顺序从扑克牌中处理三张牌。我只想动画三张牌的位置 - 比如第一张动画在第一张牌的位置立即开始并持续0.4秒,第二张以相同的持续时间在0.4秒后开始,最后一张在0.8秒后开始。我无法弄清楚如何做到这一点!下面的代码不起作用。也许我需要使用CAGroupAnimation,但我不知道如何制作一组顺序 同一财产上的动画!

        CGFloat beginTime = 0.0;

        for (Card *c in cards) {
            CardLayer *cardLayer = [cardToLayerDictionary objectForKey:c];

            CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
            anim.fromValue = [NSValue valueWithCGPoint:stockLayer.position];
            anim.toValue = [NSValue valueWithCGPoint:wasteLayer.position];
            anim.duration = 0.4;
            anim.beginTime = beginTime;
            beginTime += 0.4;
            cardLayer.position = wasteLayer.position;
            [cardLayer addAnimation:anim forKey:@"position"];

            …
         }

2 个答案:

答案 0 :(得分:4)

像爱因斯坦一样,time is relative。您的所有图层beginTime都是relative to the timespace of their superlayer ---因为它不是动画,所以它们都是相同的。

看起来有两种可能的解决方案:

  1. 获取绝对时基并设置相对于它的每个图层的动画beginTime

    int i = 0; float delay = 0.4;
    for (Card *c in cards) {
        // ...
        float baseTime = [cardLayer convertTime:CACurrentMediaTime() fromLayer:nil];
        anim.beginTime = baseTime + (delay * i++);
        // ...
    }
    
  2. 将每张卡片的动画包裹在一个组中。出于某种原因,我不太了解,这将这些动画放在一个共同的时间刻度上,即使这些组彼此分开。 It's worked for some,但我有点不愿相信它 - 看起来像是远处的怪异行为。

  3. 无论哪种方式,您可能还希望图层保持在动画结束时的位置。你可以让动画“坚持”如下:

    anim.fillMode = kCAFillModeForwards;
    anim.removedOnCompletion = NO;
    

    但是这可能会给你带来麻烦---图层的模型位置仍然是它开始的位置,如果你在动画之后调整它(比如,拖动卡片),你可能会得到奇怪的结果。因此,将卡片处理动画包装在CATransaction中可能是合适的,在CATransaction上设置完成块以设置图层的最终位置。


    说到带有完成块的[CATransaction begin]; [CATransaction setCompletionBlock:^{ [CATransaction begin]; [CATransaction setCompletionBlock:^{ card3Layer.position = wasteLayer.position; }]; card2Layer.position = wasteLayer.position; [CATransaction end]; }]; card1Layer.position = wasteLayer.position; [CATransaction end]; ,您可以使用它们来按顺序发生隐式动画(如果由于某些其他原因您没有使用显式动画):

    {{1}}

答案 1 :(得分:0)

以下递归方法是我可以做的最好的链接动画。我使用CATransactionposition属性设置动画,并设置一个块,对下一张卡进行递归调用。

-(void)animateDeal:(NSMutableArray*)cardLayers {
    if ([cardLayers count] > 0) {
        CardLayer *cardLayer = [cardLayers objectAtIndex:0];
        [cardLayers removeObjectAtIndex:0];

         // ...set new cardLayer.zPosition with animations disabled...

        [CATransaction begin];
        [CATransaction setCompletionBlock:^{[self animateDeal:cardLayers];}];
        [CATransaction setAnimationDuration:0.25];
        [cardLayer setFaceUp:YES];
        cardLayer.position = wasteLayer.position;
        [CATransaction commit];
    }
}

当然,这并不能解决重叠时间间隔的链接问题。