我在swift中有以下不编译的代码:
class CustomView: NSView {
override func drawRect(dirtyRect: NSRect) {
var contextPointer: COpaquePointer = NSGraphicsContext.currentContext()!.graphicsPort()
var context: CGContext? = contextPointer as? CGContext
CGContextSetRGBFillColor(context, 1, 0, 0, 1)
CGContextFillRect(context, CGRectMake(0, 0, 100, 100))
CGContextFlush(context)
}
}
我如何转换copaqupointer到CGContext?
从开发者预览版5开始,NSGraphicsContext
现在有了CGContext
属性。它还没有文档化,但它在头文件中:
@property (readonly) CGContextRef CGContext NS_RETURNS_INNER_POINTER NS_AVAILABLE_MAC(10_10);
这有点难看;如果graphicsPort()方法被更新为直接返回CGContextRef(如UIGraphicsGetCurrentContext()
),而不是一个void*,那就更好了。我把这个扩展添加到NSGraphicsContext
,现在把它扫到地毯下面:
extension NSGraphicsContext {
var cgcontext: CGContext {
return Unmanaged<CGContext>.fromOpaque(self.graphicsPort()).takeUnretainedValue()
}
}
只要在需要CGContext的地方调用NSGraphicsContext.currentContext().cgcontext
即可。
这似乎正在编译:
var contextPointer = NSGraphicsContext.currentContext()!.graphicsPort()
let context = UnsafePointer<CGContext>(contextPointer).memory
你就快到了。试试这段代码
class CustomView: NSView {
override func drawRect(dirtyRect: NSRect) {
var contextPointer = NSGraphicsContext.currentContext()!.graphicsPort()
var context = UnsafePointer<CGContext>(contextPointer).memory
CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0)
CGContextFillRect(context, CGRectMake(0, 0, 100, 100))
CGContextFlush(context)
}
}
在Xcode 6.3/Swift 1.2中,NSGraphicsContext.currentContext()!.graphicsPort
返回UnsafeMutablePointer<Void>
,你可以使用unsafeBitCast
将其转换为CGContextRef
,因为它只是一个C指针。这只是重新解释指针值,因此应该与C强制点强制转换完全相同。
let p1 = NSGraphicsContext.currentContext()!.graphicsPort
let ctx = unsafeBitCast(p1, CGContextRef.self)
请注意,这样的重新解释强制转换总是非常危险的,只有在你确定自己在做什么的时候才会使用。