5

I'm porting an NSView to Swift and I need to use Quartz CGContextAddPath.

import Cocoa

class MYView: NSView {

    init(frame: NSRect) {
        super.init(frame: frame)
    }

    override func drawRect(dirtyRect: NSRect) {
        super.drawRect(dirtyRect)


        NSColor .redColor() .set()
        NSRectFill(self.bounds)
        var p :CGMutablePathRef = CGPathCreateMutable()
        var ctx =  NSGraphicsContext.currentContext().graphicsPort()
        CGContextAddPath(ctx, p) // compiler rejects this line

    }

}

How do you understand this error message ?

Cannot convert the expression's type 'Void' to type 'CGContext!'

The Swift signature of CGContextAddPath is:

func CGContextAddPath(context: CGContext!, path: CGPath!)

What is my error ?

When I use this:

let context = UnsafePointer<CGContext>(ctx).memory

I now have a runtime error:

Jun 3 15:57:13 xxx.x SwiftTest[57092] <Error>: CGContextAddPath: invalid context 0x7fff73bd0060. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

Here is the code that I'm currently using:

import Cocoa

class MYView: NSView {

    init(frame: NSRect) {
        super.init(frame: frame)
    }

    override func drawRect(dirtyRect: NSRect) {
        super.drawRect(dirtyRect)

        var p :CGMutablePathRef =  CGPathCreateMutableCopy( CGPathCreateWithRoundedRect(self.bounds, 10, 10, nil))
        var ctx =  NSGraphicsContext.currentContext().graphicsPort()
        let context = UnsafePointer<CGContext>(ctx).memory

        CGContextAddPath(context, p) // compiler no longer rejects this line
        var blueColor = NSColor.blueColor()
        CGContextSetStrokeColorWithColor(context, NSColor.blueColor().CGColor)
        CGContextSetLineWidth(context, 2)
        CGContextStrokePath(context)

    }

}
user3585425
  • 171
  • 9

2 Answers2

10

As of Swift 1.0

If your deployment target is 10.10 you can use the convenience method introduced with Yosemite.

let context = NSGraphicsContext.currentContext().CGContext

If you have to support 10.9 you'll have to cast the context manually as per below.

let contextPtr = NSGraphicsContext.currentContext().graphicsPort
let context = unsafeBitCast(contextPtr, CGContext.self)
klotz
  • 1,951
  • 2
  • 22
  • 27
user3585425
  • 171
  • 9
1

Use NSGraphicsContext.currentContext().graphicsPort(). It returns void*. You have to cast it to CGContextRef

let ctx = UnsafePointer<CGContext>(NSGraphicsContext.currentContext().‌​graphicsPort()).memo‌​ry
fnc12
  • 2,241
  • 1
  • 21
  • 27
  • Swift is a relatively new language. May you explain exactly how you cast it to a CGContextRef ? – user3585425 Jun 09 '14 at 09:49
  • It is a good question. Try this: let ctx = UnsafePointer(NSGraphicsContext.currentContext().graphicsPort()).memory – fnc12 Jun 09 '14 at 13:47
  • This does not work (doesn't draw), and leads to this error: This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update. – user3585425 Jun 09 '14 at 13:59