Swift на OS X: как получить доступ к текущему CGContext для рисования -[NSView drawRect:]
Настроить:
Xcode 6.1
OS X 10.9.5
Цель приложенияSwift Mac для документов
Вопрос:
Я использую Swift, чтобы сделать приложение для Mac Cocoa (НЕ iOS!). У меня есть обычай NSView
подкласс. Я хотел бы переопределить -drawRect:
и получить доступ к текущему CGContext
рисовать, используя API-интерфейсы CoreGraphics.
Тем не менее, я не могу получить доступ к текущему CGContext
в Swift (то, что я делал сотни раз в 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?
НОТА:
Я определенно хочу использовать API CoreGraphics. Если использование CoreGraphics API в Swift полностью невозможно, пожалуйста, не отвечайте на предложения о том, как использовать API рисования AppKit (мне все равно, проще ли они). Я хочу знать, как использовать CoreGraphics из Swift на OS X.
2 ответа
К несчастью, CGContext
доступно только в 10.10+. Есть также graphicsPort
, но у него есть тип UnsafeMutablePointer<Void>
(и, по-видимому, нужно несколько спорить, чтобы восстановить жизнеспособный CGContext
), и это устарело в 10.10.
Если это не представляется возможным, вы можете создать растровый контекст, используя CGBitmapContextCreate
и втянуть в это; затем вы можете извлечь из него изображение и нарисовать его, чтобы увидеть результаты.
пример
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 можно обновить на
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
}
}