OS X上的Swift:如何访问当前的CGContext以进行绘图 - [NSView drawRect:]

问题描述 投票:13回答:2

Setup:

Xcode 6.1 OS X 10.9.5 Swift Mac基于文档的应用程序目标

Question:

我正在使用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中绘图?

NOTE:

我肯定想使用CoreGraphics API。除非在Swift中使用CoreGraphics API是完全不可能的,否则请不要回答有关如何使用AppKit绘图API的建议(我不在乎它们是否更容易)。我想知道如何在OS X上使用Swift的CoreGraphics。

xcode macos cocoa swift cgcontext
2个回答
9
投票

不幸的是,CGContext仅适用于10.10+。还有graphicsPort,但它有类型UnsafeMutablePointer<Void>(并且可能必须在某种程度上纠缠以恢复可行的CGContext),它在10.10中被弃用。

如果这似乎不可行,你可以使用CGBitmapContextCreate创建一个位图上下文并绘制成;然后你可以从中检索图像并绘制它以查看结果。


24
投票

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.
        }
    }
}

0
投票

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
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.