1

我一直在尝试创建一系列动画,依次处理扑克牌中的三张牌。我只想为三张卡片的位置设置动画——比如第一个动画立即从第一张卡片的位置开始并持续 0.4 秒,第二个动画在 0.4 秒后以相同的持续时间开始,最后一个动画在 0.8 秒后开始。我不知道该怎么做!下面的代码不起作用。也许我需要使用 a 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"];

            …
         }
4

2 回答 2

4

正如爱因斯坦所说,时间是相对的。您所有的图层beginTime相对于它们的超级图层的时间空间--- 因为它不是动画,所以它们最终都是一样的。

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

  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. 将每张卡片的动画包装成一个组。出于某种原因,我不太明白,这将这些动画放在一个共同的时间尺度上,即使这些组彼此分开。它对某些人有用,但我有点不愿意相信它——看起来像是远处的恐怖动作。

无论哪种方式,您可能还希望图层保持在动画结束时的位置。您可以像这样使动画“粘”起来:

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

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


说到CATransaction带有完成块的 s ,您可以使用它们来使隐式动画按顺序发生(如果由于其他原因您没有使用显式动画):

[CATransaction begin];
[CATransaction setCompletionBlock:^{
    [CATransaction begin];
    [CATransaction setCompletionBlock:^{
        card3Layer.position = wasteLayer.position;
    }];
    card2Layer.position = wasteLayer.position;
    [CATransaction end];
}];
card1Layer.position = wasteLayer.position;
[CATransaction end];
于 2012-04-18T06:52:09.063 回答
0

以下递归方法是我可以做的最好的链接动画。我使用 aCATransactionposition属性设置动画并设置一个块来递归调用下一张卡片。

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

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

于 2012-04-20T15:38:22.393 回答