Autant que j'ai compris jusqu'à présent, chaque fois que j'attire quelque chose dans le drawrect: d'un UIView, tout le contexte est effacé puis redessiné.
Donc, je dois donc faire quelque chose comme ça pour dessiner une série de points: p>
Méthode A: Dessinez tout sur chaque appel fort> p> ce qui signifie que je dois stocker tous mes points ( C'est bien) et les ré-dessinez tous, un par un, chaque fois que je veux ajouter un nouveau. Malheureusement, cela donne à mes terribles performances et je suis sûr qu'il y a une autre façon de le faire, plus efficacement. P> EDIT: Utiliser le code de MRMAGE, j'ai fait ce qui suit, qui est malheureusement aussi lent et que la couleur se mélangeait 'T Travailler. Toute autre méthode que je pourrais essayer? P> Méthode B: Enregistrement des dessins précédents dans un uiImage et dessinez uniquement les nouveaux trucs et cette image forte> p> EDIT:
Après tout, j'ai combiné l'une des méthodes mentionnées ci-dessous avec redessiner uniquement dans le nouveau recto. Le résultat est:
Méthode rapide: strong> p> merci tout le monde! p> p> p>
5 Réponses :
Combien d'ellipses allez-vous dessiner? En général, les graphismes principaux devraient pouvoir attirer rapidement beaucoup d'ellipses rapidement.
Vous pouvez cependant mettre en cache vos anciens dessins à une image (je ne sais pas si cette solution est plus performante, toutefois): P >
UIGraphicsBeginImageContext(self.frame.size); CGContextRef ctx = UIGraphicsGetCurrentContext(); // ctx is now the image's context [cachedImage drawAtPoint:CGPointZero]; // only plot new ellipses here... [cachedImage release]; cachedImage = [UIGraphicsGetImageFromCurrentImageContext() retain]; UIGraphicsEndImageContext(); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextDrawImage(context, self.bounds, maskRef); //draw the mask CGContextClipToMask(context, self.bounds, maskRef); //respect alpha mask CGContextSetBlendMode(context, kCGBlendModeColorBurn); //set blending mode [cachedImage drawAtPoint:CGPointZero];
Je ne dessine pas beaucoup, disons-nous environ 100. Mais avec le travail supplémentaire (dessinant une image sur chaque traction: et masquant les ellipses dessus), il est lent, même sur un 3GS.
Vous pouvez également essayer de masquer après avoir peint les ellipses (peut-être en dessinant d'abord à un tampon, puis en tirant de la mémoire tampon sur votre vue).
Dans le code ci-dessus, vous dites "CTX" mais signifie "contexte" non? J'essaie de voir votre méthode maintenant de voir si cela fait une différence.
Non, votre code ne fonctionne pas droit. Je violerai un peu avec elle en utilisant un uiimage pour stocker le contenu de mon contexte.
J'ai édité ma question initiale pour inclure la mise en œuvre à l'aide de vos conseils. Malheureusement, c'est juste aussi lent ...
Si vous ne changez que une petite partie du contenu de UIVIEW chaque fois que vous dessinez (et que le reste du contenu reste le même), vous pouvez l'utiliser. Plutôt que de redessiner tout le contenu de l'UIView chaque fois que vous pouvez marquer uniquement les zones de la vue qui ont besoin de redessiner à l'aide de Bien sûr, tout cela signifie également que votre - [uiview SetNeedsDisplayInrect:] code> au lieu de
- [UIView SetNeedsDisplay] < / code>. Vous devez également vous assurer que le contenu graphique n'est pas effacé avant de dessiner en réglant
View.clearScontextBeforeRawing = Oui; Code> P>
Drawrect: CODE> La mise en œuvre doit respecter le paramètre rectoire, qui devrait alors être une petite sous-section de la section de votre version complète (à moins que quelque chose d'autre accueille le recto complet) et ne tirer que dans cette partie. P>
Si " View.ClearStextExtBeforeRawing = non; i>" a fait ce qu'il dit dans la documentation qu'il devrait faire, tout le dessin devrait être incrémental, non? Mais ce n'est pas ...
Votre dessin n'est pas incrémental, sauf si vous vous assurez que votre drawrect: la mise en œuvre ne dessine que les sections mises à jour. Le moyen standard de marquer "sections mises à jour" (sections sales) utilise SetNeedsDisplayInrect :. Si vous définissez ClearScontentBeforeRawing = Non, puis remplissez tout le contexte avec le contenu de toute façon, votre prestation de performance est petite.
Vous pouvez enregistrer votre CGPath en tant que membre de votre classe. Et utilisez-le dans la méthode de tirage, vous devez créer uniquement le chemin lorsque les points changent, mais pas à chaque fois que la vue est redessinée, si les points sont incrémentiels, continuez simplement à ajouter les ellipses au chemin. Dans la méthode Drawrect, il vous suffira d'ajouter le chemin
CGContextAddPath(context,dotsPath); -(CGMutablePathRef)createPath { CGMutablePathRef dotsPath = CGPathCreateMutable(); for (Drop *drop in myPoints) { CGPathAddEllipseInRect ( dotsPath,NULL, CGRectMake(drop.point.x - drop.size/2, drop.point.y - drop.size/2, drop.size, drop.size)); } return dotsPath; }
Vient d'essayer ça aussi. Cela pourrait être un peu plus rapide que les autres méthodes, mais c'est toujours assez lent. Je vais essayer de le combiner avec le tiroir: méthode et voyez si cela le fait. Merci.
Les classes de l'objectif-C n'ont pas de "membres", ils ont des variables d'instance, ou "ivars".
Si je comprends votre problème correctement, j'essaierais de dessiner à un cgbitmapcontext code> au lieu de l'écran directement. Ensuite, dans le drawrect code>, dessinez uniquement la partie du bitmap pré-rendu nécessaire à partir du paramètre
rect code>. P>
Je n'ai rien essayé comme ça. Je vais probablement essayer d'essayer. Si vous avez un code qui montre comment cela est fait, je l'apprécierais.
++ C'est ma méthode de choix. Je viens de blt code> le tout. Il élimine le clignotant et donne l'illusion de dessiner instantanément.
Si vous êtes capable de mettre en cache le dessin comme une image, vous pouvez profiter du support de corniment d'UIVIEW. Ce sera beaucoup plus rapide que d'utiliser Quartz, car Quartz fait son dessin dans des logiciels.