2013-12-11 213 views
7

我剛剛創建了一個關鍵幀動畫是這樣的:關鍵幀動畫的關鍵時間

[UIView animateKeyframesWithDuration:10 delay:0 options:0 animations:^{ 
    [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:.1 animations:^{ 
     view.alpha = 0; 
    }]; 
} completion:nil]; 

而且這是被創建一個CAKeyframeAnimation

(lldb) po [self.layer animationForKey:@"opacity"] 
<CAKeyframeAnimation:0x10a6364b0; keyTimes = (
    0, 
    "0.1", 
    1 
); values = (
    1, 
    0, 
    0 
); calculationMode = linear; delegate = <UIViewKeyframeAnimationState: 0x10a6358d0>; fillMode = both; timingFunction = easeInEaseOut; duration = 10; keyPath = opacity> 

問:

的整個動畫應該需要10秒,不透明度動畫10 * 0.1 = 1秒,對吧?當我看動畫時,變化的動畫方式超過1秒。

爲什麼?

+0

調試輸出看起來是正確的(從0到1秒動畫從100%到0%,那麼爲從0%到0%動畫再過9秒)。你能描述你所看到的嗎?你是否在其他地方改變了不透明度?你還沒有在模擬器中打開慢動畫,對吧? –

+0

是的,CAKeyframeAnimation看起來完全正確。我看到的是,不透明度正在改變2 - 2.5秒,而不是一個。我不會在任何地方改變它,並且慢動畫關閉。 –

+1

如果您自己創建關鍵幀動畫(不是通過UIView方法),您是否看到相同的東西? –

回答

8

原因是動畫的定時功能不是線性的。

「時間和空間是相對的概念。」 - 相對論

層的理論和動畫使用分層定時系統,其中每個對象都有自己的本地時間,這取決於其父母和其自己的時間參數。

例如,動畫具有定義其調步的定時功能。 UIKit創建的動畫的默認定時功能是易入緩出定時功能,該功能定義緩慢開始,在整個持續時間中加速並在完成之前再次減速的時間。它使得流暢的動畫不會突然啓動或停止。然而,當你需要精確的時機時,它也會隨着你的關鍵幀動畫的關鍵時刻而變得煩人。

您可以通過將UIViewAnimationOptionCurveLinear選項傳遞給animateKeyframesWithDuration:delay:options:animations:completion:方法來禁用易於緩出時間。我不確定是否需要將UIViewAnimationOptions中的值轉換爲UIViewKeyframeAnimationOptions,並且文檔中沒有提及任何相關內容。也許更好(但更詳細)的方法是嵌入關鍵幀動畫塊這樣的標準動畫塊內:

[UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ 
    [UIView animateKeyframesWithDuration:0 /*inherited*/ delay:0 options:0 animations:^{ 
     [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:.1 animations:^{ 
      view.alpha = 0; 
     }]; 
    } completion:nil]; 
} completion:nil]; 
+0

我通過了兩個小時,想知道爲什麼這個* $!§動畫不是線性的,即使我傳遞了'UIViewKeyframeAnimationOptionCalculationModeLinear'(加上它的默認值)。你先生救了我,謝謝。 – AncAinu

+0

我無意中偶然發現了這個答案。我自己多年來一直在做這件事,它確實解決了這個問題,但我仍然無法確切知道爲什麼我需要通過將標準的'UIView'動畫嵌入到KeyFrameAnimation中來以這種方式「破解」它。它工作,我知道,但我的好奇心癢癢我:-) +1分析。 – Unheilig

+0

@Nicolas這似乎不再適用於iOS 9。任何選擇? – Xzya