2010-03-25 12 views
5

Sto iniziando a imparare a utilizzare l'animazione UIView. Così ho scritto le seguenti righe:setAnimationRepeatAutoreverses non si è comportato come mi aspettavo

[UIView beginAnimations:nil context:NULL]; 

[UIView setAnimationDuration:2.0]; 
[UIView setAnimationRepeatCount:2]; 
[UIView setAnimationRepeatAutoreverses:YES]; 

CGPoint position = greenView.center; 
position.y = position.y + 100.0f; 
position.x = position.x + 100.0f; 
greenView.center = position; 

[UIView commitAnimations]; 

In questo caso, l'UIView (una scatola verde) è tornato e anteriori 2 volte. Fin qui tutto bene, MA ho scoperto che dopo lo spostamento due volte, il riquadro verde è finito saltato nella "nuova posizione" (posizione.x + 100.0f, posizione.y + 100.0f) invece di tornare alla posizione originale (posizione.x, posizione.y). Ciò rende l'animazione piuttosto strana (come dopo che il riquadro torna alla posizione originale causata da setAnimationRepeatAutoreverses, salta alla nuova posizione nell'ultimo microsecondo!)

Qual è il modo migliore per rendere la casella verde NOT salta alla nuova posizione all'ultimo minuto?

risposta

1

Ho avuto esattamente lo stesso problema con l'utilizzo di animazioni UIView sulla proprietà alpha. La parte peggiore è che l'animazione salta alla posizione "finale" prima dello l'animazioneDidStop: il messaggio di delega viene inviato, il che significa che non è possibile impostare manualmente lo stato originale lì.

La mia soluzione era quella di utilizzare i messaggi animationDidStop delegato per creare un nuovo blocco di animazione, e la stringa tutti insieme:

- (void)performAnimation 
{ 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationDidStopSelector:@selector(phase1AnimationDidStop:finished:context:)]; 

    // Do phase 1 of your animations here 
    CGPoint center = someView.center; 
    center.x += 100.0; 
    center.y += 100.0; 
    someView.center = center; 

    [UIView commitAnimations]; 
} 

- (void)phase1AnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context 
{ 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationDidStopSelector:@selector(phase2AnimationDidStop:finished:context:)]; 

    // Do phase 2 of your animations here 
    CGPoint center = someView.center; 
    center.x -= 100.0; 
    center.y -= 100.0; 
    someView.center = center; 

    [UIView commitAnimations]; 
} 

- (void)phase2AnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context 
{ 
    // Perform cleanup (if necessary) 
} 

È possibile stringa insieme i blocchi di animazione che si desidera in questo modo. Sembra uno spreco di codice, ma fino a quando Apple non ci darà una proprietà [UIView setAnimationFinishesInOriginalState:] o qualcosa di simile, questo è l'unico modo per risolvere questo problema.

+0

In realtà, se seguo direttamente il codice, la vista continuerà a volare verso l'angolo in alto a sinistra. Non abbiamo davvero bisogno di creare un'animazione. Basta fare -100 per entrambe le xey del centro dovrebbe essere sufficiente. – user222292

+0

Non sono sicuro di cosa intendi: puoi chiarire cosa c'è che non va nel codice che ho dato? –

2

Ho scoperto che utilizzare un numero pari per setAnimationDuration terminerà l'animazione ripetuta nella sua posizione iniziale e quindi pop alla posizione finale dopo la fine dell'animazione. Se imposto setAnimationDuration a metà ciclo, l'animazione ripetuta terminerà nella posizione finale. Questo è un modo più semplice per gestire l'animazione rispetto all'utilizzo di setAnimationDidStopSelector: method.

// Repeat Swimming 
CGPoint position = swimmingFish.center; 
position.y = position.y - 100.0f; 
position.x = position.x - 100.0f; 

[UIView beginAnimations:nil context:nil]; 
[UIView setAnimationDuration:1.0f]; 
[UIView setAnimationRepeatCount:2.5]; 
[UIView setAnimationRepeatAutoreverses:YES]; 

swimmingFish.center = position; 
+0

Ho usato 2.1f e sembrava OK per me .. – Sam

+1

Questo non funziona per me (XCode 4.5.2 e iOS6). – Alex

Problemi correlati