Swift on OS X: How to access the current CGContext for drawing in -[NSView drawRect:]
Example
Swift 3+
class CustomView: NSView {
private var currentContext : CGContext? {
get {
if #available(OSX 10.10, *) {
return NSGraphicsContext.current?.CGContext
} else if let contextPointer = NSGraphicsContext.currentContext()?.graphicsPort {
let context: CGContextRef = Unmanaged.fromOpaque(COpaquePointer(contextPointer)).takeUnretainedValue()
return context
}
return nil
}
}
private func saveGState(drawStuff: (ctx:CGContextRef) -> ()) -> () {
if let context = self.currentContext {
CGContextSaveGState (context)
drawStuff(ctx: context)
CGContextRestoreGState (context)
}
}
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
saveGState { ctx in
// Drawing code here.
}
}
}
Swift 2
class CustomView: NSView {
private var currentContext : CGContext? {
get {
if #available(OSX 10.10, *) {
return NSGraphicsContext.currentContext()?.CGContext
} else if let contextPointer = NSGraphicsContext.currentContext()?.graphicsPort {
let context: CGContextRef = Unmanaged.fromOpaque(COpaquePointer(contextPointer)).takeUnretainedValue()
return context
}
return nil
}
}
private func saveGState(drawStuff: (ctx:CGContextRef) -> ()) -> () {
if let context = self.currentContext {
CGContextSaveGState (context)
drawStuff(ctx: context)
CGContextRestoreGState (context)
}
}
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
saveGState { ctx in
// Drawing code here.
}
}
}
Unfortunately, CGContext
is only available in 10.10+. There’s also graphicsPort
, but it has type UnsafeMutablePointer<Void>
(and presumably must be wrangled somewhat to recover a viable CGContext
), and it’s deprecated in 10.10.
If that doesn’t seem viable, you could create a bitmap context using CGBitmapContextCreate
and draw into that; then you can retrieve an image from it and draw that to see the results.