CAMediaTiming ( 時間協議)詳解
有一種通過CAAnimation實現的協議叫做CAMediaTiming,也就是CABasicAnimation和CAKeyframeAnimation的基類(指CAAnimation)。像duration,beginTime和repeatCount這些時間相關的屬性都在這個類中。大體而言,協議中定義了8個屬性,這些屬性通過一些方式結合在一起,准確的控制著時間。文檔中每個屬性只有幾句話,所以很有可能在看這篇文章之前你都已經讀過了,但是我覺得使用可視化的圖形能更好的解釋時間。
可視化的CAMediaTiming
為了顯示相關屬性的不同時間,無論是他們自己還是混合狀態,我都會動態的將橙色變為藍色。下面的塊狀顯示了從開始到結束的動畫過程,時間線上每一個標志代表一秒鐘。你可以看到時間線上的任意一點,當前顏色即表示動畫中的當前時間。比如,duration像下面一樣可視。
我們都知道,CALayer和CAAnimation都實現了CAMediaTiming 協議,因此在Core Animation中,理解CAMediaTiming協議中的屬性是非常必要的,但是蘋果的文檔中對於各個屬性描述太簡單,對初學者容易理解,這篇文章主要幫助理解CAMediaTiming協議中各個屬性的含義。
CAMediaTiming Protocol提供了8個屬性,下面將分別講解。
CAMediaTiming / 時間協議
/** 當前時間2秒以後開始動畫 */ keyFrameAnim.beginTime = CACurrentMediaTime() + 2; /** 截止到當前時間,動畫已經執行了2秒, 注意,如果執行的時間大於動畫時長,則表示動畫已經執行過。 */ keyFrameAnim.beginTime = CACurrentMediaTime() - 2;
7.timeOffset,時間軸偏移量。將時間軸移動至偏移位置,再執行整個動畫時長。假設動畫時長3秒,偏移量為8,則開始位置為8 % 3 = 2,再執行3秒,即在整個時長的1/ 3處結束。
8.CACurrentMediaTime,返回系統當前的絕對時間(從本次開機開始),單位秒。
/** The receiver does not appear until it begins and is removed from the presentation when it is completed. */ kCAFillModeRemoved; // (默認)動畫模型的呈現效果直至開始時才顯示,並在動畫結束後移除。 /** The receiver does not appear until it begins but remains visible in its final state when it is completed. */ kCAFillModeForwards; // 動畫模型的呈現效果直至開始時才顯示,但在動畫結束後仍然顯示最後的狀態。 /** The receiver appears in its initial state before it begins but is removed from the presentation when it is completed. */ kCAFillModeBackwards; // 動畫開始之前,動畫模型顯示其初始呈現效果,但在動畫結束後移除。 /** The receiver appears in its initial state before it begins and remains visible in its final state when it is completed. */ kCAFillModeBoth; // 動畫開始之前,動畫模型顯示其初始呈現效果,並且在動畫結束後仍然顯示最後的狀態。
暫停/繼續動畫demo
- (IBAction)pauseBtnClicked:(id)sender { /** 判斷當前圖層對象是否有針對postion屬性的動畫效果 */ if ([self.layer.presentationLayer animationForKey:@"position"]) { // 通過絕對時間獲取圖層的本地時間 CFTimeInterval localTime = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil]; /** 將圖層的時間流逝速度設置為0,以暫停動畫 */ self.layer.speed = 0; // 設置圖層的時間軸偏移量,為繼續動畫做准備 self.layer.timeOffset = localTime; } } - (IBAction)continueBtnClicked:(id)sender { /** 判斷當前圖層對象是否有針對postion屬性的動畫效果 */ if ([self.layer.presentationLayer animationForKey:@"position"]) { // 獲取上次暫停時的時間軸偏移量 CFTimeInterval timeOffset = self.layer.timeOffset; // 重置時間軸偏移量 self.layer.timeOffset = 0; // 速度還原為1 self.layer.speed = 1; // 重置開始時間 #warning 此處嚴重不理解。 self.layer.beginTime = 0; // 計算暫停時間和當前時間的差值 CFTimeInterval localTime = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil]; CFTimeInterval timeSincePause = localTime - timeOffset; // 從上一次暫停處開始 self.layer.beginTime = timeSincePause; } }
感謝閱讀,希望能幫助到大家,謝謝大對本站的支持!