Xcode 6.1
OS X 10.9.5
Swift Macドキュメントベースのアプリケーションターゲット
私はSwiftを使用してCocoa Macアプリを作成しています(iOSではありません!)。カスタムのNSView
サブクラスがあります。 -drawRect:
をオーバーライドし、現在のCGContext
にアクセスして、CoreGraphicsAPIを使用して描画を実行したいと思います。
ただし、Swift(ObjCで何百回も行ったこと)の現在のCGContext
にアクセスできないようです)。コードは次のとおりです。
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
私は何が間違っているのですか? Swiftで描画するために現在のCGContext
を取得するにはどうすればよいですか?
CoreGraphicsAPIを絶対に使いたいです。 SwiftでCoreGraphicsAPIを使用することは完全に不可能でない限り、代わりにAppKit描画APIの使用方法に関する提案を返信しないでください(簡単かどうかは関係ありません)。知りたいです。 OSXで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.
}
}
}
Swift 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.
}
}
}
Eporediese sの回答は次のように更新できます
Swift 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
}
}