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
    }
}
Другие вопросы по тегам