2016-01-03 2 views
0

J'ai deux UIButton, le premier bouton va déclencher le - beginAnimation de CustomeView et l'autre déclenchera le - endAnimation. quand je presse rapidement ces deux boutons à leur tour, comme begin -> end -> begin -> end -> begin -> end, j'ai constaté que le CADisplayLink ne peut pas arrêter. Qui plus est, le taux de tir de - rotate est plus de 60fps, est devenu 60 -> 120 -> 180, tout comme il y a plus d'un CADisplaylink dans mon RunLoop principal, donc est-il possible de le réparer? Et je dois garder le CADisplaylink courir avant venu à zéro alpha de la vue, donc je mets le [self.displayLink invalidate]; dans le bloc d'achèvement, peut-être cela va causer ce problème?CADisplayLink ne peut pas s'arrêter après invalide

@interface CustomeView : UIView 
@end 

@implementation CustomeView 

- (void)beginAnimation // triggered by a UIButton 
{ 
    [UIView animateWithDuration:0.5 animations:^{ self.alpha = 1.0; }]; 
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(rotate)]; 
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
} 

- (void)endAnimation // triggered by another UIButton 
{ 
    [UIView animateWithDuration:0.5 animations:^{ self.alpha = 0.0; } completion:^(BOOL finished) { 
     [self.displayLink invalidate]; 
    }]; 
} 

- (void)rotate 
{ 
    // .... 
} 

Répondre

0

Si vous appelez -beginAnimation avant que le bloc d'achèvement dans -endAnimation a couru - c'est-à-dire avant que l'animation de 0,5 seconde soit terminée - vous écraserez l'ancien self.displayLink avec le nouveau. Ensuite, lorsque le bloc d'achèvement s'exécute, vous invalidez le nouveau lien d'affichage, pas l'ancien.

Utilisez une variable intermédiaire pour capturer la valeur de self.displayLink qui contient le lien d'affichage que vous souhaitez invalider. En outre, pour faire bonne mesure, définissez self.displayLink à zéro lorsque vous avez terminé avec elle.

- (void)beginAnimation // triggered by a UIButton 
{ 
    [UIView animateWithDuration:0.5 animations:^{ self.alpha = 1.0; }]; 

    if (self.displayLink != nil) { 
     // You called -beginAnimation before you called -endAnimation. 
     // I'm not sure if your code is doing this or not, but if it does, 
     // you need to decide how to handle it. 
    } else { 
     // Make a new display link. 
     self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(rotate)]; 
     [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    } 
} 

- (void)endAnimation // triggered by another UIButton 
{ 
    if (self.displayLink == nil) { 
     // You called -endAnimation before -beginAnimation. 
     // Again, you need to determine what, if anything, 
     // to do in this case. 
    } else { 
     CADisplayLink oldDisplayLink = self.displayLink; 
     self.displayLink = nil; 

     [UIView animateWithDuration:0.5 animations:^{ self.alpha = 0.0; } completion:^(BOOL finished) { 
      [oldDisplayLink invalidate]; 
     }]; 
    } 
} 
+0

Merci, utile! – Illya