2009-10-13 10 views
24

Mam animację , która animuje właściwość CALayer, np. bounds.origin. Chcę móc obserwować zmianę właściwości obiektu w czasie, ale tak naprawdę nie znalazłem metody, która działa w 100%.Obserwowanie animowanych zmian właściwości w CALayerze

  1. Próbowałem przy użyciu KVO (obserwacja klucz-wartość) na presentationLayer „s bounds.origin zasób keypath. System narzeka, że ​​obiekt zostaje uwolniony, zanim jego obserwatorzy zostaną uwolnieni, co doprowadzi mnie do przekonania, że ​​warstwa prezentacji jest tylko tymczasowa. Obserwowanie presentationLayer.bounds.origin jako keypath nie działa.

  2. Próbowałem utworzyć właściwość na innej warstwie i animować ją, na przykład przez zadeklarowanie @property i utworzenie na tej warstwie @dynamic. Jednak ta nowa właściwość zmienia się tylko wtedy, gdy uzyskuje się dostęp do warstwy prezentacji (na przykład na końcu animacji), nie wydaje się, aby była aktualizowana podczas działania animacji.

  3. użyłem needsDisplayForKey na nieruchomości w # 2, który powoduje wyzwolenia aktualizacji podczas animacji, ale dla tych zagadnień:

    • to działa tylko wtedy, gdy CALayer ma niezerową ramkę. Ponieważ ta warstwa może być warstwą lub podklasą CAShapeLayer, może mieć zerową ramkę.
    • Wygląda na to, że wyzwala ona dla tej warstwy setNeedsDisplay, ale ponieważ w rzeczywistości nie rysuję tej warstwy tylko monitorując zmianę właściwości, nie chcę powodować jej odświeżania.
  4. Próbowałem zaplanować NSTimer, a w ramach próbki oddzwaniania timera presentationLayer. To również działa, ale w przypadku tych problemów:

    • Czasomierz prawdopodobnie byłby nieco niezsynchronizowany z aktualizacją animacji.
    • Od czasu do czasu pierwotna animacja zostaje wyprzedzona przez inną animację, trudno jest uzyskać timer do uruchomienia, gdy animacja jest uruchomiona i tylko wtedy, gdy animacja jest uruchomiona.

Wszelkie sugestie? Wszystko to będzie na iPhoneOS 3.0/3.1.

Odpowiedz

5

Myślę, że wymieniłeś wszystkie możliwości. W rzeczywistości nie zdawałem sobie nawet sprawy z tego, że # 2 i # 3 i napisałem the book on Core Animation. ;-)

KVO nie jest dostępny dla tych nieruchomości. Byłoby miło, gdyby tak było, ale wierzę, że to ma związek z kosztami, które musiałoby ponieść. Wartość będzie aktualizować się bardzo często i będzie musiała oddzwonić do dowolnego obserwatora.

W każdym razie znalazłem NSTimer jako najbardziej niezawodne podejście, ale teraz nie jestem pewien z tego, co powiedziałeś. Co sprawia, że ​​uważasz, że timer nie jest zsynchronizowany? Dlaczego trudno jest uruchomić timer tylko po uruchomieniu animacji? Nie możesz po prostu sprawdzić stanu, w którym chcesz oddzwonić, a następnie nic nie robić, jeśli warunek nie zostanie spełniony?

Pozdrawiam.

+1

NSTimery są uruchamiane bez względu na to, kiedy aktualne warstwy są aktualizowane, zawsze znajdowały się one nieco za lub przed krokiem animacji warstwy. To, czego potrzebuję, to otrzymywanie powiadomienia * w tym samym czasie *, co animacja warstwy. Najlepiej jest użyć programu CADisplayLink (tylko iPhone 3.1) lub utworzyć sztuczną warstwę z opcją # 3, aby otrzymać powiadomienie. W końcu, ponieważ środowisko jest tak dynamiczne, zrezygnowałem z używania Core Animation, aby to zrobić - teraz używam NSTimer lub CADisplayLink do automatycznego przewijania. –

+0

Podczas autowyprowadzania, w warstwie, którą zastępuję, istnieje już animacja automatycznego przewijania, a czasami początkowa animacja musi być opóźniona o 1/2 sekundy. Dlatego trudno jest * wiedzieć * kiedy animacja jest uruchomiona. Wywołania delegatów CAAnimation również nie następują natychmiastowo, więc jest szansa, że ​​dowolny kod w zależności od tego będzie niezsynchronizowany z tym, co już się stało w warstwie animowanej. –

+2

Zobacz na przykład: http://developer.apple.com/mac/library/qa/qa2004/qa1385.html. Doktor Apple mówi: "NSTimer to zegar ogólnego przeznaczenia, nie jest to zegar powiązany z urządzeniem wyświetlającym, interwał i moment, w którym timer zaczął strzelać, nie mają związku z chwilą pionowego odświeżania. Oznacza to, że proste podejście tworzenia timera w "60.0" Hz jest skazane na niepowodzenie - zegar będzie dryfował w stosunku do rzeczywistej częstotliwości odświeżania, a będziesz spadać lub podwójne klatek.Oznacza to również, że zegar wywołuje aplikację w dowolnym punkcie do odśwież ... " –

Powiązane problemy