2009-09-21 14 views
5

Dodaję podstawową animację do gry karcianej, nad którą pracuję. (Moja pierwsza aplikacja na iPhone'a).Modyfikowanie widoku kontenera animacji iPhone'a przed rozpoczęciem animacji

Tworzę niestandardową klasę UIView "AnimationContainer", która zmienia obraz z image1 na image2, przechodząc z rect1 na rect2. Moim ostatecznym zamiarem jest posiadanie do czterech takich pojemników jednocześnie wykonujących swoje przejścia.

Problem mam jest to, że nie jest wyświetlana animacja Image1 ... więc pojawia się tylko ostatnia połowa przejścia flip.

Jeśli jednak najpierw zresetuję animację, dotykając opcji Resetuj, wszystko działa idealnie. Innymi słowy, jeśli wielokrotnie wciskam klawisz Flip, otrzymam tylko połowę zmiany ... ale jeśli najpierw wciśniemy Resetuj, wszystko działa idealnie na jedną klapkę.

Jak więc ustawić animację, aby zresetowała się poprawnie?

Poniżej znajduje się kod, zrzut ekranu, a oto link do pełnej: Project Zip File 700k.

alt text http://www.robsteward.com/cardflip.jpg

- (void)displayWithImage1 {  //RESET button calls this 
    self.frame = rect1; 
    [image2 removeFromSuperview]; 
    [self addSubview:image1]; 
    [self setNeedsDisplay]; //no help: doesn't force an update before animation 
} 

- (void)runTheAnimation {  //FLIP button calls this 
    [self displayWithImage1]; //<---this is what the reset button calls 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.5]; 
    [UIView setAnimationTransition:transition forView:self cache:NO]; 
    self.frame = rect2; 
    [image1 removeFromSuperview]; 
    [self addSubview:image2]; 
    [UIView commitAnimations]; 
} 

Dzięki!

+0

Podjęłam półobrzykowe obejście. Dodałem animację "dummy" i uczyniłem moją klasę delegatem dla jej setAnimationDidStopSelector. Animacja obojętna trwa 0,0 i po prostu przesuwa widok na rect1. Kiedy wywoływany jest selektor zatrzymania manekina, robię "prawdziwy" animowany klapkowy kod z góry. W pełni funkcjonalny i wygląda na to, że co najmniej 4 mogą być uruchomione jednocześnie. Yay, ja. LOL – Rob

+1

Okazuje się, że obejście to może wytworzyć nawet pół sekundy opóźnienia, więc zaczynam nagrodę. Musi istnieć sposób, aby wysłać widok kontenera z dwoma obrazami i przenieść go z jednego do drugiego w jednym przejściu. – Rob

Odpowiedz

12

Potrzebna jest pętla rysunkowa do przejścia, aby przerysować widok przed wykonaniem animacji. Ten kod jest przykładem "narysuj to, a kiedy nadejdzie kolejna pętla zdarzeń, rób to inną rzecz". Często zdarza się to w kodzie UI. Twoje pierwsze obejście próbuje tego samego, ale w znacznie bardziej skomplikowany sposób.

- (void)_runTheAnimation { 
    // Moved here from -runTheAnimation 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.5]; 
    [UIView setAnimationTransition:transition forView:self cache:NO]; 
    self.frame = rect2; 
    [image1 removeFromSuperview]; 
    [self addSubview:image2]; 
    [UIView commitAnimations]; 
} 

- (void)runTheAnimation {  //FLIP button calls this 
    [self displayWithImage1]; 
    [self performSelector:@selector(_runTheAnimation) withObject:nil afterDelay:0.0]; 
} 
+1

Awesome! Dziękuję bardzo. Nie byłem wcale pewien, że selektory nie zostały wykonane natychmiast. Teraz wszystko działa świetnie. Obrót o wartości 200 rep był niewielką ceną do zapłacenia. Spędziłem z tym 10 godzin. – Rob

+1

Selektory są wysyłane natychmiast, jeśli zostaniesz o to poproszony (-forform Selector :) Powyższa metoda jest -performSelector: withObject: afterDelay :, która planuje na biegu, aby selektor został wysłany w pewnym momencie w przyszłości. Opóźnienie o wartości 0 efektywnie oznacza "następnym razem, gdy pętla uruchamiająca jest iterowana." Selektory same opisują komunikat, który należy przekazać do obiektu. Przekazanie tej wiadomości odbywa się za pomocą metod performSelector ... –

+1

Fajnie, myślę, że rozumiem. Nadal staram się przyspieszyć działanie Cocoa, Objective-C i wszystkich rzeczy iPhone ... ale teraz uczę się szybciej. Dzięki jeszcze raz. – Rob