Drawing at Cocoa with Swift Creates an Error

Cocoa Drawing Error: invalid context 0x0

Yes, you need a context to draw into. Best practice is probably to override the drawRect method of your subclass where the context is already setup for you automatically, something like that:

import Foundation
import AppKit

public class MyWindowView: NSView {

private func drawARectAtPoint(point: NSPoint) {
let rectToDraw:NSRect = NSMakeRect(point.x, point.y, 200, 200)
NSColor.blackColor().setStroke()
var bezier = NSBezierPath(rect: rectToDraw)
bezier.lineWidth = 2
bezier.stroke()
}

private var clickPoint: NSPoint?

override public func mouseDown(theEvent: NSEvent) {
clickPoint = theEvent.locationInWindow
setNeedsDisplayInRect(bounds)
}

override public func drawRect(dirtyRect: NSRect) {
// do all your drawing here
if let clickPoint = clickPoint {
drawARectAtPoint(clickPoint)
}
}
}

Unable to draw into a new PDF with Cocoa/Swift/Quartz

You're mixing two worlds here. CoreGraphics and high-level Cocoa drawing calls. To make the Cocoa drawing work, you need to create an NSGraphicsContext based on the CoreGraphics one and make it the current context:

let graphicsContext = NSGraphicsContext(CGContext: context!, flipped:true)
NSGraphicsContext.saveGraphicsState()
NSGraphicsContext.setCurrentContext(graphicsContext)

Simple drawing with mouse on cocoa swift

I created a simple demo which can draw something with mouse event. You can change the any parameters if you want like color or line width etc.

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

@IBOutlet weak var window: NSWindow!

func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
let view = DrawView()
view.translatesAutoresizingMaskIntoConstraints = false
self.window.contentView?.addSubview(view)

self.window.contentView?.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|", options: [], metrics: nil, views: ["view": view]))
self.window.contentView?.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|", options: [], metrics: nil, views: ["view": view]))
}

func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}

}

class DrawView: NSView {
var path: NSBezierPath = NSBezierPath()

override func mouseDown(with event: NSEvent) {
path.move(to: convert(event.locationInWindow, from: nil))
needsDisplay = true
}

override func mouseDragged(with event: NSEvent) {
path.line(to: convert(event.locationInWindow, from: nil))
needsDisplay = true
}

override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)

NSColor.black.set()

path.lineJoinStyle = .roundLineJoinStyle
path.lineCapStyle = .roundLineCapStyle
path.lineWidth = 10.0
path.stroke()
}
}

Sample Image

Drawing in NSView from background operation has no effect

Typically these problems go away if you send your view updating code back to the main queue from within your background task:

DispatchQueue.main.async {
// your view update code
}

If there's not too many place inside your doTheBackgroundStuff you could just sprinkle those in for view updates, i.e. whenever you access your mainView.

Otherwise it helps to re-group things into parts that do non-UI heavy lifting and then push the view updates to Dispatch.main.async at the end.

Cocoa giving error: Error: doClip: empty path

Poking around with class-dump and nm, I found that it's a function in CoreGraphics (Quartz 2D). It's not declared in the headers, so it's a private function.

Break on doClip in the debugger, then move down the stack and see whether any of your code is drawing at that time. If so, you're probably trying to clip to an empty path. If a third-party framework you're using is involved, you should file a bug with its authors.

If you're not calling it (and you shouldn't), and a third-party framework is not implicated, it's probably a bug in one of the Apple frameworks. You should report it to Apple.

How can I draw a simple line?(OS X)

Try doing it inside drawRect (NSView):

import Cocoa

final class Line: NSView {
override func drawRect(dirtyRect: NSRect) {
let myPath = NSBezierPath()
myPath.moveToPoint(CGPoint(x: 20, y: 20))
myPath.lineToPoint(CGPoint(x: 100, y: 100))
myPath.stroke()
}
}

final class ViewController: NSViewController {

override func viewDidLoad() {
super.viewDidLoad()
let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
let line = Line(frame: frame)
view.addSubview(line)
}

override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}

}

Getting error: Use of unresolved identifier 'NSRectFill', but __NSRectFill works, why?

Starting in Swift 3, NSRectFill has been made a method of NSRect / CGRect. So you should have called bounds.fill() instead.

Deep down though, it may still relies on some Core Foundation routines like __NSRectFill. It's better that you avoid those double-underscored functions since they are low-level system stuffs that are poorly documented (at least publicly).

eraser not working in iOS drawing

I have solved this issue, the problem and below is the code which works perfectly

case :ERASE
{
CGPoint mid1 = midPoint(m_previousPoint1, m_previousPoint2);
CGPoint mid2 = midPoint(m_currentPoint, m_previousPoint1);

[m_curImage drawAtPoint:CGPointMake(0, 0)];
CGContextRef context = UIGraphicsGetCurrentContext();

[self.layer renderInContext:context];
CGContextMoveToPoint(context, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context, kCGLineCapRound);

CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineWidth(context, self.lineWidth);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
CGContextSetShouldAntialias(context, YES);
CGContextSetAllowsAntialiasing(context, YES);
CGContextSetFlatness(context, 0.1f);

CGContextSetAlpha(context, self.lineAlpha);
CGContextStrokePath(context);
}

Regards
Ranjit.

This solved my issue, if anyone has the same issue, please implement this.



Related Topics



Leave a reply



Submit