如何转换copaqupointer在swift到某些类型(CGContext?)特别是)



我在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)

请注意,这样的重新解释强制转换总是非常危险的,只有在你确定自己在做什么的时候才会使用。

最新更新