Podstawowa struktura kodu animacji/konwencje

Podczas nauki Core Animation bardzo szybko nauczyłem się, że jeśli nie zrobisz tego dobrze, uzyskasz naprawdę dziwne niezdefiniowane zachowanie. W tym celu mam kilka pytań, które pomogą mi lepiej zrozumieć to koncepcyjnie.

  • Moja podklasa NSView deklaruje następujące elementy init. Ten widok jest widokiem podrzędnym normalnego widoku opartego na warstwie.

    [self setLayer:[CALayer layer]];
    [self setWantsLayer:NO];
    

    Po tym, kiedy iw jakich sytuacjach powinienem odnosić się do siebie, a nie do [warstwy siebie]? Manipulowałem TYLKO warstwą za pomocą wyraźnych i niejawnych animacji, trzymając się z dala od [self setFrame:] itp. i używając [[self layer] setPosition] itp.

  • Problem z tym podejściem polega na tym, że rzeczywista klatka widoku pozostaje w jednym miejscu przez wszystkie zastosowane animacje. Co jeśli mój widok ma odbierać zdarzenia myszy? Na przykład mam widok, który wykorzystuje animację rdzenia i jest przeciągany myszą. Czy istnieje sposób, aby w jakiś sposób zsynchronizować ramkę widoku z bieżącym stanem warstwy prezentacji, aby móc odbierać odpowiednie zdarzenia myszy?

  • Jeśli chodzi o warstwę prezentacji, najwyraźniej jest ona dostępna tylko wtedy, gdy trwa animacja. Czy istnieje jakaś właściwość warstwy, która może mi powiedzieć, gdzie jest ona WŁAŚCIWIE wizualnie, nawet gdy animacja nie jest w toku?


person cemulate    schedule 16.05.2009    source źródło


Odpowiedzi (2)


Myślę, że musisz trochę przeformułować swoje pytanie. Wydaje się, że istnieje jakieś ukryte nieporozumienie, ale tak naprawdę nie wyrażasz tego zbyt jasno. Tytuł twojego pytania sugeruje, że chcesz zrozumieć coś bardziej teoretycznego, ale twoje rzeczywiste pytanie sugeruje, że szukasz czegoś bardziej konkretnego. Zobaczę, czy uda mi się wyjaśnić kilka rzeczy.

  • presentationLayer dostarcza informacji o bieżącym stanie warstwy podczas „w locie”.

  • W przypadku braku animacji informacje presentationLayer i warstwa będą identyczne. Zapytaj o granice, ramkę lub położenie warstwy, aby dowiedzieć się, gdzie aktualnie się znajduje w jej macierzystej przestrzeni współrzędnych.

  • NSViews musi mieć włączone tworzenie warstw, aby móc wykonywać animacje.

  • Upewnij się, że nie wykonujesz animowania za pomocą wyraźnej animacji i nie ustawiasz wartości warstwy, którą animujesz. Animacje nie zmieniają automatycznie właściwości animowanych warstw. Musisz samodzielnie zmienić właściwość na wartość końcową, w przeciwnym razie po prostu "cofa się" do wartości początkowej.

  • Jeśli chcesz animować widok, a nie warstwę, możesz użyć proxy animatora, takiego jak [[view animator] setFrame:newFrame];

  • Zawijaj wywołania animatora w CATrasaction, aby zmienić takie rzeczy, jak czas trwania animacji.

Daj mi znać, jeśli potrzebujesz wyjaśnienia, aktualizując swoje pytanie. Dostarczenie odpowiedniego kodu naprawdę pomogłoby zidentyfikować problemy, z którymi masz problemy.

person Matt Long    schedule 19.08.2010

Po pierwsze, chcesz użyć [self setWantsLayer: YES]. Ponadto ważne jest, aby wywołać -setLayer: przed -setWantsLayer:, jeśli chcesz podać określoną podklasę CALayer (taką jak CAScrollLayer); jeśli chcesz tylko zwykłego CALayer, po prostu zadzwoń do -setWantsLayer:, a zostanie on stworzony dla Ciebie. Co więcej, po prostu zaznacz opcję „chce warstwy” w programie Interface Builder.

Po drugie, cały punkt korzystania z widoku opartego na warstwach polega na tym, że możesz nadal używać zwykłych metod NSView i uzyskać bezpłatne efekty „tweeningu” CoreAnimation. Jeśli chcesz używać CoreAnimation jako jedynego sposobu przenoszenia elementów, to właściwym sposobem na to jest utworzenie widoku opartego na warstwie, który zawiera twoją hierarchię prezentacji pure-CALayer.

Nie zajrzałem do żadnych darmowych samouczków CoreAnimation, ale zdecydowanie mogę polecić książka na ten temat. Mają też screencast dostępne przez autora książki.

person Jim Dovey    schedule 17.05.2009