2010-07-05 8 views
0

J'essaie de faire une animation de machine à sous où les rouleaux tournent. Pour ce faire, j'utilise drawRect pour dessiner des images dans une classe personnalisée qui hérite de UIView. J'utilise un nstimer pour mettre à jour la position des images et appeler [self setNeedsDisplay] pour mettre à jour le dessin. Dans le simulateur, il semble très bon, cependant, sur l'appareil, il est très laggy. Je me demandais si je faisais quelque chose de mal avec ma méthode de dessin ou s'il y avait de meilleures solutions.Problème de performance avec DrawRect et NSTimer

- (void)drawRect:(CGRect)rect 
{ 
    [image1 drawInRect:CGRectMake(0, image1Position, 98, 80)]; 
    [image2 drawInRect:CGRectMake(0, image2Position, 98, 80)]; 
    [image3 drawInRect:CGRectMake(0, image3Position, 98, 80)]; 
} 


- (void)spin 
{ 
    // move each position down by 10 px 
    image1Position -= MOVEMENT; 
    image2Position -= MOVEMENT; 
    image3Position -= MOVEMENT; 
    // if any of the position <= -60 reset to 180 
    if(image1Position < -50) 
    { 
     image1Position = 180; 
    } 
    if(image2Position < -50) 
    { 
     image2Position = 180; 
    } 
    if(image3Position < -50) 
    { 
     image3Position = 180; 
    } 
    [self setNeedsDisplay]; 
} 

-(void)beginSpinAnimation 
{  
    timer = [NSTimer scheduledTimerWithTimeInterval:SCROLL_TIME target:self selector:@selector(spin) userInfo:self repeats:YES]; 
} 

Mon CoreAnimation tentative avec UIScrollView:

- (void) spinToNextReel 
{ 
    int y = self.contentOffset.y + 80; 

    // if the current >= last element reset to first position (-30) 
    if(y >= (80 *(elementCount+1) - 30)) 
    { 
     y = -30; 
    } 

    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationDuration:SCROLL_TIME]; 
    [UIView setAnimationCurve:UIViewAnimationCurveLinear]; 

    self.contentOffset = CGPointMake(0, y); 

    [UIView commitAnimations]; 

    if (!isSpinning && targetY == y) 
    { 
     NSLog(@"target is %d, y is %d", targetY, y); 

     if(timer) 
     { 
      [timer invalidate]; 
      timer = nil; 
     } 
     [self playSound]; 
    } 
} 

Répondre

4

Je dirais que la recherche en CoreAnimation. Il est fait pour faire ce que vous voulez faire ici. Ce sera beaucoup plus rapide que ce que vous faites ici. Pour ce qui est de la lenteur, appeler drawInRect n'est pas la chose la plus rapide au monde. Qu'est-ce que SCROLL_TIME?

+1

Plus rapide et moins gênant. –

+0

Appuyé. Surtout sur un appareil mobile. CoreAnimation est bien meilleur (comme dans "fast" et "battery-friendly") que le meilleur que vous pourrez faire seul dans Cocoa. –

+0

SCROLL_TIME est à .05 c'est juste un flottant défini. Je pense que de toutes les réponses, la réponse est CoreAnimation. Y a-t-il un bon exemple simple de CoreAnimation de Apple? Sur une note de côté, lors d'une tentative précédente, j'ai utilisé un CoreAnimation avec UIScrollView (vérifier le post édité ci-dessus). Cependant, il provoque un léger hickup quand il essaie de s'arrêter sur la dernière bobine, et c'est pourquoi j'ai essayé de dessine-le moi-même. –

1

Vous voulez utiliser CoreAnimation, ce sera beaucoup plus facile et plus efficace. Cela dit, si vous insistez pour essayer d'animer manuellement cette façon, vous faites quelques mauvais chose:

  1. Ne tentez pas de déplacer une quantité constante sur des intervalles fixes, les événements de la minuterie peut être retardée, et si elles Cela entraîne-t-il une animation inégale, puisque vous déplacez un montant constant par événement et non par intervalle de temps. Vous devez enregistrer l'horodatage réel chaque fois que vous l'animez, le comparer à l'horodatage précédent et déplacer un nombre de pixels approprié. Cela se traduira par des quantités égales de mouvement, même si les événements sont retardés (en fait, vous allez perdre des images). Ne pas utiliser un NSTimer, utiliser un CADisplayLink. Cela liera votre dessin au taux de rafraîchissement natif du système et le synchronisera avec tout autre dessin en cours. Je sais que je l'ai déjà dit, mais apprendre et utiliser CoreAnimation, vous serez beaucoup plus heureux.