2015-03-19 3 views
12

Setup:

Xcode 6.1
OS X 10.9.5
Swift Mac dokumentenbasierte Anwendung ZielSwift auf OS X: Wie die aktuelle CGContext zuzugreifen in zum Zeichnen - [NSView drawRect:]

Frage:

I Swift bin mit einem Cocoa Mac app machen (NICHT iOS!). Ich habe eine benutzerdefinierte NSView Unterklasse. Ich möchte -drawRect: überschreiben und auf die aktuelle CGContext zugreifen, um einige Zeichnungen mit den CoreGraphics-APIs zu erstellen.

Allerdings kann ich nicht auf den aktuellen CGContext in Swift zugreifen (etwas, das ich Hunderte von Male in ObjC getan habe). Hier ist mein Code:

import Cocoa 

class Canvas: NSView { 
    override func drawRect(dirtyRect: CGRect) { 
     if let ctx: CGContext! = NSGraphicsContext.currentContext()?.CGContext { 
      // do drawing 
     } 
    } 
} 

Wenn ich laufe, bekomme ich sofort Absturz in der ersten Zeile meiner drawRect Umsetzung:

-[NSWindowGraphicsContext CGContext]: unrecognized selector sent to instance 0x60800005e840 

Was mache ich falsch? Wie hole ich die aktuelle CGContext zum Zeichnen in Swift?

HINWEIS:

Ich möchte auf jeden Fall die Core Graphics API verwenden. Wenn die Verwendung der CoreGraphics-API in Swift nicht unmöglich ist, antworten Sie bitte nicht mit Vorschlägen zur Verwendung von AppKit-Zeichnungs-APIs (es ist mir egal, ob sie einfacher sind). Ich möchte wissen, wie Sie CoreGraphics von Swift auf OS X verwenden.

+1

hier OP. Sofort nachdem ich diese Frage gestellt hatte, erkannte ich, dass '- [NSGraphicsContext CGContext]' eine 10.10 API ist. Und wie ich schon sagte, ich entwickle auf 10.9 (obwohl mein Ziel das 10.10 Base SDK verwendet). Also, das ist das Problem. Diese Frage ist im Grunde dumm. Dies ist buchstäblich die erste Zeile des Swift-Codes, den ich geschrieben habe, also tapple ich immer noch herum, und ich hatte gerade angenommen, dass ich syntaktisch etwas falsch mache. –

Antwort

8

Leider ist CGContext nur in 10.10 + verfügbar. Es gibt auch graphicsPort, aber es hat den Typ UnsafeMutablePointer<Void> (und vermutlich muss etwas gerungen werden, um eine lebensfähige CGContext wiederherzustellen), und es ist in 10.10 veraltet.

Wenn das nicht praktikabel erscheint, könnten Sie einen Bitmap-Kontext erstellen, indem Sie CGBitmapContextCreate verwenden und darin zeichnen; dann können Sie ein Bild von ihm abrufen und zeichnen, um die Ergebnisse zu sehen.

+1

Gotcha, danke. Es sieht so aus, als müsste ich sofort auf 10.10 umsteigen, um mir die Sache zu erleichtern. Das werde ich jetzt tun. –

+0

Gehen Sie dazu und viel Glück-Swift 1.2b3 in Xcode 6.3b3 ist echt. –

21

Beispiel

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

Das ist sehr elegant! Allerdings funktioniert es nur in Swift 2? –

Verwandte Themen