user3585425 user3585425 - 2 months ago 29
Swift Question

How to use Implicitly Unwrapped Optionals?

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)

}

}

Answer

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)
Comments