[Résolu] dessiner dans une vue avec drawRect: lag
Salut,
j'ai ce code pour dessiner dans une vue, le lineArray représente les points déjà dessinés par d'anciens "touchs" et pointArray est ce qui est dessiné pendant le touchMoved.
Après quelques secondes, les lignes "laguent" et ne sont plus dessinées de manière fluide, il semble que la boucle soit trop "lourde" pour afficher les nouvelles lignes en suivant le doigt, sauriez-vous comment éviter ça? (Dessiner de manière fluide même après 2,3 secondes) :
if ([self.lineArray count] > 0){
for ( int j=0; j<self.lineArray.count; j++ ){
NSArray *lArray = [self.lineArray objectAtIndex:j];
CGContextBeginPath(context);
//path
CGPoint startPoint=CGPointFromString([lArray objectAtIndex:0]);
CGContextMoveToPoint(context, startPoint.x, startPoint.y);
for ( int i=1; i<[lArray count]; i++){
CGPoint endPoint = CGPointFromString( [lArray objectAtIndex:i] );
CGContextAddLineToPoint(context, endPoint.x, endPoint.y);
}
//color
NSNumber *num = [self.colorArray objectAtIndex:j];
NSUInteger color = [num intValue];
UIColor *theColor = [self.possibleColor objectAtIndex:color];
CGContextSetStrokeColorWithColor(context, [theColor CGColor] );
CGContextSetLineWidth(context, 3);
CGContextStrokePath(context);
}
}
//pointArray
if ([self.pointArray count] > 0){ //quasiment la meme chose
Merci
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Peux-tu me donner un exemple?
En mettant une seule fois beginPath au départ de drawRect, et strokePath à la fin sans les mettre dans les boucles? Après environ 70 points dans l'array, (ça vient assez rapidement, après 3 sec max) les lignes ne suivent pas les points et font des "triangles", comme si la boucle était encore trop lourde :
Conserve le CGPath en variable d'instance, c'est ça que veut dire Ali.
Tu le gardes dans une @property, tu le construis au fur et à mesure de tes touchs... et dans ton drawRect tu ne fais que l'ajouter à ton Context et appeler "stroke" dessus.
En fait tu n'as même plus besoin de ton "pointsArray" que tu utilises actuellement : au lieu de garder les points dans une @property, remplir ce tableau à chaque Touch dans ta vue ou e sais pas quand, et finalement reconstruire le path à partir de ces points à chaque fois dans drawRect... autant construire directement le CGPath et lui ajouter des points là où jusqu'à présent tu ajoutais tes points à ton pointsArray.
La methode drawRect est quand même sensés être relativement rapide, elle ne doit faire que dessiner un truc existant normalement.
C'est un peu le même principe qu'avec la methode cellForRowAtIndexPath quand tu fais une UITableView, où cette methode est sensée retourner rapidement en tout cas be pas porter des opérations longues type calculs ou download d'images ou autre : tu construits tout cela en amont et dans ces méthodes tu ne fais qu'utiliser les objets (ton bezierrPath en l'occurrence) déjà construit au préalable.
Merci Aligator et Céroce, donc je dois mal m'y prendre, j'ai une erreur :
Même en mettant un point par défaut au départ : (dans initwithCoder, la vue vient du storyboard)
Et le code :
Donc le point initial que tu essayes de mettre au début après to CGPathCreateMutable il faut le placer avec un CGPathMoveToPoint, on ne peut pas commencer un path avec comme toute première instruction un CGPathAddLineToPoint car il manque le point initial.
Et sinon, pourquoi ne pas faire le démarrage du path dans le touchBegan pour démarrer une nouvelle ligne a chaque fois que tu commences à toucher l'écran et la terminer quand tu relâches ? Parce que sinon là avec ton code si tu relâches le doigt de l'écran et que tu tapes ailleurs ça va continuer le trait !
Super merci, ça marche très bien,
EDIT: il fallait alloc-init le previousArray au cas où il est nul, sinon on ajoute un objet à un objet null. Sujet résolu.
ancien message : alors j'aimerais simplement enregistrer les paths (dans une classe avec sa couleur) dans le NSUserDefaults, mais le loadData ne renvoie rien, previousArray est (null), je ne comprend pas pourquoi? (Aussi, existe-t-il un moyen d'avoir la même chose qu'un "prettyJson" avec NSUserDefault? J'ai trouvé "dictionaryRepresentation" mais j'ai obtenu des chiffres entre ces crochets "<...>").
Voici le code :