2010-04-11 8 views
0

je peux tirer beaucoup de choses en utilisant ceci:Pourquoi je ne peux pas dessiner dans une boucle? (L'utilisation UIView dans l'iPhone)

NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"dummy2.png" ofType:nil]; 
UIImage *img = [UIImage imageWithContentsOfFile:imagePath]; 
image = CGImageRetain(img.CGImage); 

CGRect imageRect; 

double x = 0; 
double y = 0; 

for (int k=0; k<someValue; k++) { 
    x += k; 
      y += k; 

     imageRect.origin = CGPointMake(x, y); 
     imageRect.size = CGSizeMake(25, 25);  
     CGContextDrawImage(UIGraphicsGetCurrentContext(), imageRect, image); 
    } 
} 

CGImageRelease(img.CGImage); 

Ainsi, il fonctionne, donc, je l'ai mis dans l'exécution d'un objet de commande de la méthode. Ensuite, je veux faire des choses similaires, mais cette fois-ci, mon méthode Execute seulement faire ceci:

NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"dummy2.png" ofType:nil]; 
UIImage *img = [UIImage imageWithContentsOfFile:imagePath]; 
image = CGImageRetain(img.CGImage); 

CGRect imageRect; 

double x = inComingX; 
double y = inComingY; 

imageRect.origin = CGPointMake(x, y); 
     imageRect.size = CGSizeMake(25, 25);  
     CGContextDrawImage(UIGraphicsGetCurrentContext(), imageRect, image); 

    CGImageRelease(img.CGImage); 

Cette fois-ci, ce qui est également une commande, et c'est la méthode d'exécution. Mais je prends la boucle pour. Je vais avoir une autre méthode qui passe le inComingX, et inComingY dans mon objet Command. méthode

Mon dessin est simplement exécuter le Cmd qui se passait dans mon drawingEngine:

-(void)drawInContext:(CGContextRef)context 
{ 
    [self.cmdToBeExecuted execute]; 
} 

J'ai aussi la méthode assign pour affecter la commande ,:

-(void)assignCmd:(Command*)cmd{ 
    self.cmdToBeExecuted = cmd; 

} 

Et c'est la façon dont je appelé le dessinEngine

for(int k=0; k<5; k++){ 
    [self.drawingEngine assignCmd:[DrawingCmd setDrawingInformation:(10*k):0:@"dummy.png"]]; 
    [self.drawingEngine setNeedsDisplay]; 
} 

Il peut dessiner, mais le plus triste est qu'il ne dessine que le dernier. Pourquoi? et comment le réparer? Je peux dessiner toutes les choses dans mon code First, mais après avoir sorti la boucle à l'extérieur, et utilisé la boucle dans le dernier code, il ne fait que dessiner le dernier. Aide de Plz

Répondre

4

C'est parce que setNeedsDisplay n'appelle pas réellement drawRect:. Il planifie simplement la vue à redessiner à l'instant "commode" suivant, ce qui est probable la prochaine fois, l'application rentre dans la boucle d'exécution. Puisque vous remplacez l'objet de commande mémorisé à chaque appel de la fonction d'affectation, le drawRect: est effectivement appelé, seule la dernière commande affectée est disponible et sera dessinée.

Une meilleure façon de le faire serait: ne pas oublier toutes les commandes à tirer plutôt que le dernier, par exemple dans un tableau, comme:

@interface MyCanvas { 
    ... 
    NSMutableArray* commandList; 
    ... 
} 

et ajouter des commandes à ce tableau au lieu d'attribuer un seul élément de commande:

-(void) addCommand:(Command*) cmd { 
    [self.commandList addObject: cmd]; 
} 

Les commandes doit ensuite être traité dans le procédé draw

for(Command* cmd in self.commandList) { 

    [cmd execute ...]; 
} 

Vous pouvez également définir des commandes "complexes" composées de plusieurs étapes de dessin.

(EDIT pour répondre à la question dans les commentaires): Votre code d'origine a fait le travail, car il fait le travail en un seul endroit dans une invocation unique de la méthode draw appropriée. Votre dernier code ne dessine rien du tout pendant qu'il s'exécute. Il se souvient simplement (via l'objet de commande) que quelque chose doit être fait, et avertit la vue, qu'il devrait se redessiner lors de l'occasion suivante. Il est important de noter que setNeedsDisplaypas causera toute repeindre à faire directement. Il marque simplement la vue comme "sale", qui sera reprise par un autre code dans l'exécution de Cocoa plus tard.

Il y a une autre chose dans votre code que je trouve un peu suspecte: votre méthode drawInContext: prend un argument de contexte, qui est simplement ignoré. Il n'est pas non plus transmis à la méthode execute de votre objet de commande, ni n'est installé comme une sorte de contexte de dessin "courant" dans une variable d'instance ou quelque chose comme ça. Si vous attendez que le code dans drawRect: (ou la méthode execute de la commande) utilise effectivement ce contexte, vous devez le transmettre à quiconque est supposé l'utiliser.

+0

O ... Ce n'est pas ce que je veux, comment changer mon code pour supporter de dessiner beaucoup de choses sur la vue? thz .... Mais encore une question, pourquoi mon premier code peut dessiner tout le truc? – Tattat