Drawing incrementally in a UIView (iPhone)

后端 未结 5 1438
甜味超标
甜味超标 2020-12-02 14:09

As far as I have understood so far, every time I draw something in the drawRect: of a UIView, the whole context is erased and then redrawn.

So I have to do something

相关标签:
5条回答
  • 2020-12-02 14:21

    You can save your CGPath as a member of your class. And use that in the draw method, you will only need to create the path when the dots change but not every time the view is redraw, if the dots are incremental, just keep adding the ellipses to the path. In the drawRect method you will only need to add the path

    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;
    }
    
    0 讨论(0)
  • 2020-12-02 14:30

    If I understand your problem correctly, I would try drawing to a CGBitmapContext instead of the screen directly. Then in the drawRect, draw only the portion of the pre-rendered bitmap that is necessary from the rect parameter.

    0 讨论(0)
  • 2020-12-02 14:32

    If you are able to cache the drawing as an image, you can take advantage of UIView's CoreAnimation backing. This will be much faster than using Quartz, as Quartz does its drawing in software.

    - (CGImageRef)cachedImage {
        /// Draw to an image, return that
    }
    - (void)refreshCache {
        myView.layer.contents = [self cachedImage];
    }
    - (void)actionThatChangesWhatNeedsToBeDrawn {
        [self refreshCache];
    }
    
    0 讨论(0)
  • 2020-12-02 14:35

    How many ellipses are you going to draw? In general, Core Graphics should be able to draw a lot of ellipses quickly.

    You could, however, cache your old drawings to an image (I don't know if this solution is more performant, however):

    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];
    
    0 讨论(0)
  • 2020-12-02 14:41

    If you are only actually changing a small portion of the UIView's content every time you draw (and the rest of the content generally stays the same), you can use this. Rather than redraw all the content of the UIView every single time, you can mark only the areas of the view that need redrawing using -[UIView setNeedsDisplayInRect:] instead of -[UIView setNeedsDisplay]. You also need to make sure that the graphics content is not cleared before drawing by setting view.clearsContextBeforeDrawing = YES;

    Of course, all this also means that your drawRect: implementation needs to respect the rect parameter, which should then be a small subsection of your full view's rect (unless something else dirtied the entire rect), and only draw in that portion.

    0 讨论(0)
提交回复
热议问题