Рисование в NSView

Я пытаюсь нарисовать представление с помощью событий мыши, но xcode дает мне «недопустимый контекст». Может ли кто-нибудь сказать, когда я делаю неправильно?

class DrawingView: NSView {

var gContext:CGContextRef?

var lastPoint = NSPoint(x:0, y:0)
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var brushWidth: CGFloat = 10.0
var opacity: CGFloat = 1.0
var swiped = false

func drawLineFrom(p1:NSPoint, p2:NSPoint){

    // CGContextBeginPath(gContext)
    // CGContextSetRGBStrokeColor(gContext, 0, 0, 0, 1)
    NSColor.redColor().set() // choose color
    CGContextSetLineWidth(gContext, 10.0)

    CGContextMoveToPoint(gContext, p1.x, p1.y)
    CGContextAddLineToPoint(gContext, p2.x, p2.y)

    CGContextStrokePath(gContext)

    // self.setNeedsDisplayInRect(self.bounds)
    needsDisplay = true

}

override func mouseUp(theEvent: NSEvent) {
    swiped = true

    let droppings = theEvent.locationInWindow
    let currentPoint:NSPoint = self.convertPoint(droppings, fromView: nil)
    self.drawLineFrom(lastPoint, p2: currentPoint)

    Swift.print("Up \(currentPoint)")
    lastPoint = currentPoint
}

override func mouseDown(theEvent: NSEvent) {
    // let position = theEvent.locationInWindow
    // Swift.print("Mouse Down: \(position.x) - \(position.y)")

    if theEvent.clickCount == 1{
        let point:NSPoint = self.convertPoint(theEvent.locationInWindow, fromView: self)
        Swift.print("Point >> \(point)")
        lastPoint = point
    }

}

override func drawRect(dirtyRect: NSRect) {
    super.drawRect(dirtyRect)

    // Drawing code here.
    let context = NSGraphicsContext.currentContext()?.CGContext

    let rawContext = NSGraphicsContext.currentContext()
    rawContext?.saveGraphicsState()

    self.gContext = context

    CGContextSetRGBStrokeColor(context, 0, 0, 0, 1)
    CGContextSetLineWidth(context, 10.0)

    CGContextMoveToPoint(context, 0, 0)
    CGContextAddLineToPoint(context, 200, 200)

    CGContextStrokePath(context)
}

И вот мой отладочный вывод...

Точка >> (247.71484375, 108.34375) 25 октября 15:40:07 Основы OSX [17113]: CGContextSetFillColorWithColor: неверный контекст 0x0. Если вы хотите увидеть обратную трассировку, установите переменную среды CG_CONTEXT_SHOW_BACKTRACE. 25 октября, 15:40:07 Основы OSX [17113]: CGContextSetStrokeColorWithColor: неверный контекст 0x0. Если вы хотите увидеть обратную трассировку, установите переменную среды CG_CONTEXT_SHOW_BACKTRACE. Вверх (394.96484375, 220.5078125)


person Carlos Farini    schedule 25.10.2015    source источник


Ответы (1)


Вы не можете рисовать содержимое представления вне метода draw rect. Ошибка связана с кодом ниже:

func drawLineFrom(p1:NSPoint, p2:NSPoint) {
    NSColor.redColor().set() // choose color
    // ....
}

Вы вызываете drawLineFrom(:) из события перемещения мыши. Вы пытаетесь изменить цвет текущего графического контекста, когда контекста не существует. Чтобы перерисовать представление, вы должны запросить перерисовку, выполнив self.needsDisplay = true, а затем внести изменения в методе draw rect.

Вот пример кода:

class DrawingView: NSView {

    var point: CGPoint = CGPoint.zero

    override func mouseUp(theEvent: NSEvent) {
        // Convert the point from the window coordinate to the view coordinate
        self.point = self.convertPoint(theEvent.locationInWindow, fromView: nil) 
        // We ask to redraw the view
        self.needsDisplay = true 
        Swift.print("Up \(self.point)")
    }
}

override func drawRect(dirtyRect: NSRect) {
    super.drawRect(dirtyRect)

    // You have to draw inside this function and not outside
    // The context is only valid here and you cannot retain it to draw later
    let context = NSGraphicsContext.currentContext()?.CGContext
    // Draw here
}
person Jeremy Vizzini    schedule 04.11.2015