2011-09-18 18 views
6

Sto tentando di animare un indicatore in un campo modulo vuoto, quindi sto utilizzando il metodo seguente per animare in una posizione, invertire l'animazione e ripetere. Nel simulatore funziona bene, sul mio 3GS sembra che ci sia uno sfarfallio proprio quando viene chiamato il blocco di completamento. L'indicatore viene brevemente mostrato nella posizione centrale piuttosto che indietro alla sua origine.UIView sfarfallio animazione con autoreverse

Qualche idea sul perché questo sta accadendo? Grazie.

- (void)bounceFormIndicator { 
    if (formIndicator.superview == nil) { 
     return; 
    } 

    int bounceDistance = 24; 

    [UIView animateWithDuration:0.6 
          delay:0 
         options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction 
        animations:^{ 
         CGRect indicatorFrame = formIndicator.frame; 
         indicatorFrame.origin.x += bounceDistance; 
         formIndicator.frame = indicatorFrame; 
        }completion:^(BOOL finished){ 
         CGRect indicatorFrame = formIndicator.frame; 
         indicatorFrame.origin.x -= bounceDistance; 
         formIndicator.frame = indicatorFrame; 
         [self bounceFormIndicator]; 
        }]; 
} 
+0

Ancora non risolto, ma ho trovato un lavoro in giro. Uso l'opzione UIViewAnimationOptionRepeat e rimuovo completamente il blocco di completamento. – brianpartridge

risposta

13

Ho avuto lo stesso problema e sono andato a Apple DTS per aiutare con una soluzione alternativa.

Come per DTS, questo effetto "sfarfallio" o effetto di snap-back è il comportamento previsto ... Ho pensato che stavo facendo qualcosa di sbagliato con il mio progetto per molto tempo.

In particolare, è in questo modo perché gli stati di documentazione, per

UIViewAnimationOptionAutoreverse Esegui l'animazione all'indietro e in avanti .

Deve essere combinato con l'opzione UIViewAnimationOptionRepeat.

Per far sparire il flicker, ho dovuto fare 2 cose.

La mia implementazione era dinamica, quindi potrebbe non essere necessario implementare il primo passaggio, ma lo terrò qui solo per riferimento.

In primo luogo, ho controllato per vedere se UIViewAnimationOptionAutoreverse faceva parte delle opzioni che stavo per passare nel mio animazione e UIViewAnimationOptionRepeatnon ero ... Se è così, ho messo a nudo dalle opzioni aggiungendo una riga come:

animationOptions &= ~UIViewAnimationOptionAutoreverse; 

Per creare l'animazione di inversione senza ripetere, ho aggiunto un'animazione UIView opposta come blocco di completamento. Ho anche invertito l'allentamento se era o UIViewAnimationOptionCurveEaseIn o UIViewAnimationOptionCurveEaseOut ...

Il codice dal mio progetto segue:

L'affermazione che mette a nudo l'opzione autoreverse da animationOptions di un oggetto:

if ((animationOptions & AUTOREVERSE) == AUTOREVERSE) { 
    self.shouldAutoreverse = YES; 
    animationOptions &= ~AUTOREVERSE; 
} 

An esempio di un setter di proprietà sovrascritto che gestisce un'animazione:

-(void)setCenter:(CGPoint)center { 
    CGPoint oldCenter = CGPointMake(self.center.x, self.center.y); 

    void (^animationBlock) (void) =^{ super.center = center; }; 
    void (^completionBlock) (BOOL) = nil; 

    BOOL animationShouldNotRepeat = (self.animationOptions & REPEAT) != REPEAT; 
    if(self.shouldAutoreverse && animationShouldNotRepeat) { 
     completionBlock =^(BOOL animationIsComplete) { 
      [self autoreverseAnimation:^ { super.center = oldCenter;}]; 
     }; 
    } 
    [self animateWithBlock:animationBlock completion:completionBlock]; 
} 

Il metodo di completamento richiesto in t caso di inversione senza ripetere:

-(void)autoreverseAnimation:(void (^)(void))animationBlock { 
     C4AnimationOptions autoreverseOptions = BEGINCURRENT; 
     if((self.animationOptions & LINEAR) == LINEAR) autoreverseOptions |= LINEAR; 
     else if((self.animationOptions & EASEIN) == EASEIN) autoreverseOptions |= EASEOUT; 
     else if((self.animationOptions & EASEOUT) == EASEOUT) autoreverseOptions |= EASEIN; 

     [UIView animateWithDuration:self.animationDuration 
           delay:0 
          options:autoreverseOptions 
         animations:animationBlock 
         completion:nil]; 
} 
Problemi correlati