NSRectFill without context results in debug warnings

1k Views Asked by At

I'm trying out drawing in Objective-C with NSRect, but all the examples I find online result in a warning in the output log. It does draw on the View, but I would like to see that there are no issues reported by the debugger :).

I read some things about that the stuff you draw explicitly has to be inside a "context", but all the articles I find are way above my level at the moment.

Here's my code:

- (void)drawRect:(NSRect)rect
{
    NSColor *white = [NSColor whiteColor];
    NSColor *blue = [NSColor blueColor];
    
    [white set];
    NSRectFill([self bounds]);
    
    rect = NSMakeRect(100, 100, 50, 50);
    [blue set];
    NSRectFill(rect);
}

I get these errors:

Jul 2 16:10:49 localhost X[27220] : CGContextSetFillColorWithColor: invalid context 0x0

Jul 2 16:10:49 localhost X[27220] : CGContextSetStrokeColorWithColor: invalid context 0x0

Jul 2 16:10:49 localhost X[27220] : CGContextSetFillColorWithColor: invalid context 0x0

Jul 2 16:10:49 localhost X[27220] : CGContextSetStrokeColorWithColor: invalid context 0x0

Jul 2 16:10:49 localhost X[27220] : CGContextGetCompositeOperation: invalid context 0x0

Jul 2 16:10:49 localhost X[27220] : CGContextSetCompositeOperation: invalid context 0x0

Jul 2 16:10:49 localhost X[27220] : CGContextFillRects: invalid context 0x0

Jul 2 16:10:49 localhost X[27220] : CGContextSetCompositeOperation: invalid context 0x0

Most articles talked about using "NSGraphicsContext", but all were theoretical and I couldn't find an example of how to get that to work.

I hope someone can help :)

1

There are 1 best solutions below

1
On

When performing drawing operations, you need to provide a graphic context. The context is the place in which the drawing will occur, like a canvas for painting.

A graphic context is managed by an instance of the class NSGraphicsContext or by its CoreGraphics low-level counterpart CGContextRef. Most Cocoa drawing methods operate in the current context. If you want to create a custom context for your drawing operation, you can get the current context using +[NSGraphicsContext currentContext] and set it using +[NSGraphicsContext setCurrentContext:].

But when you implement -[NSView drawRect:], you don't need to deal with graphic contexts. Why? Because NSView automatically creates a context and sets it as the current context before calling your implementation of drawRect: then retrieves the drawn contents and displays it on screen. The obvious caveat is you must not call drawRect: directly: Instead, Cocoa will call your implementation of drawRect: when it needs to display the view. It's done automatically. The only things you can do (and need to do) is tell the view when it needs to redisplay (i.e. when its drawn contents changes) using the method -[NSView setNeedsDisplay:] with the parameter YES.