Pour autant que je l'aie compris jusqu'à présent, chaque fois que je dessine quelque chose dans le dessin: d'un UIView, tout le contexte est effacé puis redessiné.Dessin incrémentiel dans un UIView (iPhone)
donc je dois faire quelque chose comme ça pour dessiner une série de points:
Méthode A: dessin tout sur chaque appel
- (void)drawRect:(CGRect)rect {
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
for (Drop *drop in myPoints) {
CGContextAddEllipseInRect(context, CGRectMake(drop.point.x - drop.size/2, drop.point.y - drop.size/2, drop.size, drop.size));
}
CGContextSetRGBFillColor(context, 0.5, 0.0, 0.0, 0.8);
CGContextFillPath(context);
}
Ce qui signifie, je dois stocker tous mes points (c'est bon) et re-dessinez-les tous, un par un, chaque fois que je veux en ajouter un nouveau. Malheureusement, cela donne ma performance terrible et je suis sûr qu'il y a une autre façon de le faire, plus efficacement.
EDIT: En utilisant le code de MrMage j'ai fait ce qui suit, qui malheureusement est tout aussi lent et le mélange des couleurs ne fonctionne pas. Toute autre méthode que je pourrais essayer?
Méthode B: sauver la précédente puise dans un UIImage et le dessin que les nouveautés et cette image
- (void)drawRect:(CGRect)rect
{
//draw on top of the previous stuff
UIGraphicsBeginImageContext(self.frame.size);
CGContextRef ctx = UIGraphicsGetCurrentContext(); // ctx is now the image's context
[cachedImage drawAtPoint:CGPointZero];
if ([myPoints count] > 0)
{
Drop *drop = [myPoints objectAtIndex:[myPoints count]-1];
CGContextClipToMask(ctx, self.bounds, maskRef); //respect alpha mask
CGContextAddEllipseInRect(ctx, CGRectMake(drop.point.x - drop.dropSize/2, drop.point.y - drop.dropSize/2, drop.dropSize, drop.dropSize));
CGContextSetRGBFillColor(ctx, 0.5, 0.0, 0.0, 1.0);
CGContextFillPath(ctx);
}
[cachedImage release];
cachedImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext();
//draw on the current context
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, self.bounds, maskRef); //draw the mask
CGContextSetBlendMode(context, kCGBlendModeColorBurn); //set blending mode
[cachedImage drawAtPoint:CGPointZero]; //draw the cached image
}
EDIT: Après tout ce que je combine l'une des méthodes mentionner ci-dessous avec redessiner seulement dans le nouveau rect. Le résultat est le suivant: Méthode rapide:
- (void)addDotAt:(CGPoint)point
{
if ([myPoints count] < kMaxPoints) {
Drop *drop = [[[Drop alloc] init] autorelease];
drop.point = point;
[myPoints addObject:drop];
[self setNeedsDisplayInRect:CGRectMake(drop.point.x - drop.dropSize/2, drop.point.y - drop.dropSize/2, drop.dropSize, drop.dropSize)]; //redraw
}
}
- (void)drawRect:(CGRect)rect
{
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
if ([myPoints count] > 0)
{
Drop *drop = [myPoints objectAtIndex:[myPoints count]-1];
CGPathAddEllipseInRect (dotsPath, NULL, CGRectMake(drop.point.x - drop.dropSize/2, drop.point.y - drop.dropSize/2, drop.dropSize, drop.dropSize));
}
CGContextAddPath(context, dotsPath);
CGContextSetRGBFillColor(context, 0.5, 0.0, 0.0, 1.0);
CGContextFillPath(context);
}
Merci tout le monde!
Si "* view.clearsContextBeforeDrawing = NO; *" 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 ... – Dimitris
Votre dessin n'est pas incrémentiel sauf si vous vous assurez que votre implémentation drawRect: ne dessine que les sections mises à jour. La manière standard de marquer les "sections mises à jour" (sections sales) utilise setNeedsDisplayInRect :. Si vous définissez clearsContentBeforeDrawing = NO et remplissez tout le contenu avec du contenu, votre avantage en termes de performances est faible. –