Search code examples
macoscocoansviewquartz-graphicsdrawrect

Efficient drawing in NSView drawRect


I have an application I'm writing in which I'm drawing into an NSView. In mouseDown I am saving the location in my data model and then drawing a graphic at that location within the drawRect method of the view. It all works fine.

At the end of my mouseDown I was calling [self setNeedsDisplay:YES]; to force a redraw. The only thing is that the dirtyRect is always the full size of the view. I wanted to optimize this as much as possible so that I'm not redrawing the entire window for just a few changed pixels.

So now I'm calling [self drawRect:...] instead and specifying the rectangle.

Now in my drawRect I am comparing every graphic I have to see if it falls in the dirtyRect. It seems like I've traded work of drawing for work of bounds checking everything. I'm not sure I've made it any more or less efficient.

So what is the standard practice? Is it common to just redraw everything in the view and ignore the dirtyRect? Is there a nice function I can use as a test to see whether my object is in the dirtyRect?


Solution

  • You should never call -drawRect: yourself if you're trying to draw to the screen. Let AppKit call it for you. What you should do is call -setNeedsDisplayInRect: at the end of your -mouseDown:.

    Then, in -drawRect:, only draw stuff contained in the dirtyRect. You can test to see if a point is inside the dirtyRect with NSPointInRect(). There are lots of other useful functions for working with NSRect. See the documentation for the point functions and the rectangle functions.