2012-04-18 17 views
1

我一直在嘗試創建一系列動畫,依次處理撲克牌中的三張牌。我只想爲這三張牌的位置製作動畫 - 比方說第一張動畫立即在第一張牌的位置開始並持續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"]; 

      … 
     } 

回答

4

就像愛因斯坦說的,time is relative。你所有的圖層'beginTime s是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,但我有點不願意相信它---看起來像是在遙遠的幽靈行動。

無論哪種方式,你可能也希望圖層留在他們在動畫結束的位置。你可以使動畫「大棒」就像這樣:

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]; 
+0

所有這一切都很好,除非你想要圖層保留最後的「位置」屬性。 – wcochran 2012-04-20 15:29:24

+0

是的 - 這就是我在線前的最後一段。使用包含在「CATransaction」中的帶有完成塊的顯式動畫,您可以根據需要計算它們的時間(甚至是重疊),完成塊爲您提供了設置最終位置的地方。 – rickster 2012-04-23 07:00:40

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

當然,這並不能解決重疊時間間隔的鏈接問題。

+0

通過塊延遲遞歸 - 很好。如果使用顯式動畫*和*完成塊,則應該能夠獲得重疊的時間間隔:動畫會更改卡片的表觀位置,然後完成塊設置實際位置並移除動畫。 – rickster 2012-04-21 05:37:09

相關問題