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)
}
}
You can simply represent a Data type as Optional by appending ! or ? to the Type . If an optional contains a value in it, it returns value as Optional<Value> , if not it returns nil .
Implicitly unwrapping that optional means that it's still optional and might be nil, but Swift eliminates the need for unwrapping.
Unwrap an optional type with the nil coalescing operator If a nil value is found when an optional value is unwrapped, an additional default value is supplied which will be used instead. You can also write default values in terms of objects.
Forced unwrapping is an action done on the normal Optionals. Implicitly unwrapped Optionals are Optionals, usually used for class initialization and will pass values without exclamation mark when used.
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)
Use NSGraphicsContext.currentContext().graphicsPort()
. It returns void*. You have to cast it to
CGContextRef
let ctx = UnsafePointer<CGContext>(NSGraphicsContext.currentContext().graphicsPort()).memory
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With