macosswiftcocoadrawingnsbezierpath

Cocoa Drawing Error: "invalid context 0x0"


I'm trying to draw some sweet squares on my window view, but I get some strange errors. Am I doing something wrong?

Here's the code:

import Foundation
import AppKit

public class MyWindowView: NSView {

private func drawARectAtPoint(point: NSPoint) {
    let rectToDraw:NSRect = NSMakeRect(point.x, point.y, 200, 200)
    NSColor.blackColor().setStroke()
    var bezier = NSBezierPath(rect: rectToDraw)
    bezier.lineWidth = 2
    bezier.stroke()
}

override public func mouseDown(theEvent: NSEvent) {
    let clickPoint = theEvent.locationInWindow;
    self.drawARectAtPoint(clickPoint)
}
}

I set the class of my window content view to MyWindowView and when I click on that I get errors like:

Oct 21 14:57:21 ImagineCI[3467] : CGContextSetStrokeColorWithColor: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. Oct 21 14:57:21 ImagineCI[3467] : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable. Oct 21 14:57:21 ImagineCI[3467] : CGContextSetLineCap: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.


Solution

  • Yes, you need a context to draw into. Best practice is probably to override the drawRect method of your subclass where the context is already setup for you automatically, something like that:

    import Foundation
    import AppKit
    
    public class MyWindowView: NSView {
    
        private func drawARectAtPoint(point: NSPoint) {
            let rectToDraw:NSRect = NSMakeRect(point.x, point.y, 200, 200)
            NSColor.blackColor().setStroke()
            var bezier = NSBezierPath(rect: rectToDraw)
            bezier.lineWidth = 2
            bezier.stroke()
        }
    
        private var clickPoint: NSPoint?
    
        override public func mouseDown(theEvent: NSEvent) {
            clickPoint = theEvent.locationInWindow
            setNeedsDisplayInRect(bounds)
        }
    
        override public func drawRect(dirtyRect: NSRect) {
            // do all your drawing here
            if let clickPoint = clickPoint {
                drawARectAtPoint(clickPoint)
            }
        }
    }