Xcode 6.1 OS X 10.9.5 Swift Mac基于文档的应用程序目标
我正在使用Swift制作一个Cocoa Mac应用程序(不是iOS!)。我有一个自定义的NSView
子类。我想覆盖-drawRect:
,并使用CoreGraphics API访问当前的CGContext
进行绘图。
但是,我似乎无法访问Swift中的当前CGContext
(我在ObjC中已经做了数百次)。这是我的代码:
import Cocoa
class Canvas: NSView {
override func drawRect(dirtyRect: CGRect) {
if let ctx: CGContext! = NSGraphicsContext.currentContext()?.CGContext {
// do drawing
}
}
}
当我跑步时,我的drawRect
实施的第一行立即崩溃:
-[NSWindowGraphicsContext CGContext]: unrecognized selector sent to instance 0x60800005e840
我究竟做错了什么?如何获取当前的CGContext
以便在Swift中绘图?
我肯定想使用CoreGraphics API。除非在Swift中使用CoreGraphics API是完全不可能的,否则请不要回答有关如何使用AppKit绘图API的建议(我不在乎它们是否更容易)。我想知道如何在OS X上使用Swift的CoreGraphics。
不幸的是,CGContext
仅适用于10.10+。还有graphicsPort
,但它有类型UnsafeMutablePointer<Void>
(并且可能必须在某种程度上纠缠以恢复可行的CGContext
),它在10.10中被弃用。
如果这似乎不可行,你可以使用CGBitmapContextCreate
创建一个位图上下文并绘制成;然后你可以从中检索图像并绘制它以查看结果。
例
Swift 3+
class CustomView: NSView {
private var currentContext : CGContext? {
get {
if #available(OSX 10.10, *) {
return NSGraphicsContext.current?.CGContext
} else if let contextPointer = NSGraphicsContext.currentContext()?.graphicsPort {
let context: CGContextRef = Unmanaged.fromOpaque(COpaquePointer(contextPointer)).takeUnretainedValue()
return context
}
return nil
}
}
private func saveGState(drawStuff: (ctx:CGContextRef) -> ()) -> () {
if let context = self.currentContext {
CGContextSaveGState (context)
drawStuff(ctx: context)
CGContextRestoreGState (context)
}
}
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
saveGState { ctx in
// Drawing code here.
}
}
}
斯威夫特2
class CustomView: NSView {
private var currentContext : CGContext? {
get {
if #available(OSX 10.10, *) {
return NSGraphicsContext.currentContext()?.CGContext
} else if let contextPointer = NSGraphicsContext.currentContext()?.graphicsPort {
let context: CGContextRef = Unmanaged.fromOpaque(COpaquePointer(contextPointer)).takeUnretainedValue()
return context
}
return nil
}
}
private func saveGState(drawStuff: (ctx:CGContextRef) -> ()) -> () {
if let context = self.currentContext {
CGContextSaveGState (context)
drawStuff(ctx: context)
CGContextRestoreGState (context)
}
}
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
saveGState { ctx in
// Drawing code here.
}
}
}
Eporedieses答案可以更新到
斯威夫特4
private var currentContext : CGContext? {
get {
if #available(OSX 10.10, *) {
return NSGraphicsContext.current?.cgContext
} else if let contextPointer = NSGraphicsContext.current?.graphicsPort {
return Unmanaged.fromOpaque(contextPointer).takeUnretainedValue()
}
return nil
}
}