2009-10-13 239 views
24

我有一個CABasicAnimation,動畫的CALayer例如, bounds.origin。我希望能夠觀察隨着時間的推移而變化的財產,但還沒有真正找到一種100%有效的方法。觀察CALayer動畫屬性更改

  1. 我試圖在presentationLayerbounds.origin的keyPath使用KVO(鍵值觀察)。系統抱怨說,在觀察者被釋放之前,對象被釋放,導致我認爲表示層只是暫時的。觀察presentationLayer.bounds.origin作爲鍵路徑不起作用。

  2. 我試着在另一層上創建一個屬性,通過在該層上聲明@property並使其成爲@dynamic。然而,當訪問表示層時(例如,在動畫結束時),這個新屬性只會被改變,但在動畫運行時似乎沒有更新。

  3. 我在#2的屬性,它確實在動畫過程中觸發更新使用needsDisplayForKey,但對於這些問題:

    • 如果CALayer具有非零幀它纔會起作用。由於此圖層可能是CAShapeLayer或子類,因此它可能具有零幀。
    • 它看起來像是爲該圖層觸發setNeedsDisplay,但由於我實際上沒有繪製該圖層只監視屬性更改,我不想讓它重繪。
  4. 我試着安排一個NSTimer,並在定時器回調示例presentationLayer內。這也適用於這些問題:

    • 計時器可能會略微與動畫更新不同步。
    • 由於有時候原始動畫會被另一個動畫取代,所以在動畫運行時以及動畫運行時很難啓動計時器。

有什麼建議嗎?所有這些都將在iPhoneOS 3.0/3.1上。

回答

5

我想你已經命名了所有的可能性。事實上,我甚至沒有意識到#2和#3,我寫了the book on Core Animation。 ;-)

KVO不適用於這些屬性。如果是這樣,會很好,但我相信這樣做的原因與它需要的開銷有關。該值會更新得非常頻繁,必須回覆任何觀察員。

無論如何,我發現NSTimer是最可靠的方法,但現在我不確定你說了什麼。是什麼讓你認爲定時器不同步?爲什麼難以讓計時器只在動畫運行時觸發?你不能僅僅在定時器回調中檢查你想要的條件,並且如果條件不滿足則不做任何事情?

最好的問候。

+1

NSTimers被激發而不考慮實際圖層何時被更新,它們總是稍微落後或在圖層動畫步驟的前面。我需要的是與圖層動畫同時通知*。最好的辦法是使用CADisplayLink(僅限iPhone 3.1)或使用選項#3的人工圖層來獲得通知。最後,因爲環境非常動態,我放棄了使用Core Animation來做到這一點 - 我現在使用NSTimer或CADisplayLink來執行自動滾動。 – 2009-10-14 21:57:58

+0

當我自動滾動時,有時在我要替換的圖層中存在一個現有的自動滾動動畫,有時最初的動畫必須延遲1/2秒。因此,在實際的動畫運行時很難*知道。 CAAnimation委託回調也不會即時發生,因此有可能任何依賴於它的代碼都與動畫圖層中已經發生的內容不同步。 – 2009-10-14 22:04:52

+2

請參閱:http://developer.apple.com/mac/library/qa/qa2004/qa1385.html。 Apple文檔說:「NSTimer是一個通用定時器,它不是一個與顯示設備相連的定時器,定時器開始觸發的時間間隔與垂直刷新時間無關,這意味着簡單的方法以「60.0」Hz創建一個定時器註定會失敗 - 定時器將相對於實際的刷新速率漂移,並且您將丟棄或加倍幀,這也意味着定時器將應用程序在任意點調入刷新...「 – 2009-10-14 22:08:54