如何通过两次鼠标点击(OSX Mac App)来绘制直线的代码?

时间:2016-07-06 10:41:38

标签: objective-c swift macos nsview

我正在尝试制作一个简单的绘图应用程序(OSX Mac应用程序),我试图弄清楚用户如何通过两次鼠标点击来绘制一条线,例如,第一次鼠标点击(mouseDown然后mouseUP)将标记该行的原点,然后第二次鼠标单击(mouseDown然后mouseUP)将标记该行的终点。在用户第二次点击结束点之前,我希望直播(在锚定终点之前)直线显示,有点像在photoshop中。 Objective-C和Swift都很好。

到目前为止,我已经......

var newLinear = NSBezierPath()

override func mouseDown(theEvent: NSEvent) {
        super.mouseDown(theEvent)
        var lastPoint = theEvent.locationInWindow
        lastPoint.x -= frame.origin.x
        lastPoint.y -= frame.origin.y
        newLinear.moveToPoint(lastPoint)
    }

override func mouseUp(theEvent: NSEvent) {
        var newPoint = theEvent.locationInWindow
        newPoint.x -= frame.origin.x
        newPoint.y -= frame.origin.y
        newLinear.lineToPoint(newPoint)
        needsDisplay = true
    }

干杯!

2 个答案:

答案 0 :(得分:0)

带有关联值的

enum非常适合您,因为您的应用程序可以扩展,并可能添加其他工具和状态。

enum State {
    case normal
    case drawingLine(from: CGPoint, to: CGPoint)
}
var state = State.normal

override func mouseDown(theEvent: NSEvent) {
    super.mouseDown(theEvent)
    var lastPoint = theEvent.locationInWindow
    lastPoint.x -= frame.origin.x
    lastPoint.y -= frame.origin.y
    state = .drawingLine(from: lastPoint, to: lastPoint)
}

override func mouseUp(theEvent: NSEvent) {
    if case .drawingLine(let firstPoint, _) = state {
        var newPoint = theEvent.locationInWindow
        newPoint.x -= frame.origin.x
        newPoint.y -= frame.origin.y
        //finalize line from `firstPoint` to `newPoint`
    }
}

override func mouseMoved(theEvent: NSEvent) {
    if case .drawingLine(let firstPoint, _) = state {
        needsDisplay = true
        var newPoint = theEvent.locationInWindow
        newPoint.x -= frame.origin.x
        newPoint.y -= frame.origin.y
        state = .drawingLine(from: firstPoint, to: newPoint)
    }
}

override func draw(_ dirtyRect: NSRect) {
    if case .drawingLine(let firstPoint, let secondPoint) = state {
        //draw your line from `firstPoint` to `secondPoint`
    }
}

答案 1 :(得分:0)

我明白你在这里想要实现的目标!所以我在andyvn22的解决方案中添加了一系列代码,这些代码应该有助于您的努力,请注意:为了简单起见,启动一个新的Xcode项目'我们可以确保一切都被覆盖在一起。

在您的新项目中右键单击' ViewController.swift'并添加新文件...选择'可可类'然后单击“下一步”,将此文件命名为“DrawingView”#39;保证子类:是' NSView'然后选择下一步。

现在您完成了设置界面,输入' Main.storyboard'并拖放自定义视图'确保根据您的偏好添加约束。现在输入您的身份检查员'而自定义视图'选中并添加“绘图视图”'在顶部上课。

我希望这是有道理的! Ok open' Assistant Editor'所以你可以查看ViewController.swift'和' Main.storyboard'同时,右键单击并从“自定义视图”中拖动'到' ViewController.swift',将此命名为' draw'并选择连接。

您会注意到Xcode已自动将@IBOutlet更新为您的子类,以及您的ViewController.swift'看起来像下面的例子。

导入Cocoa

类ViewController:NSViewController {

@IBOutlet var draw: DrawingView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
}

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

}

现在选择' DrawingView.swift'文件并清除页面上的所有内容,突出显示以下代码,复制并粘贴到您的项目中。

导入Cocoa

类DrawingView:NSView {

// >>>CODE ADDED BY LC<<<
private var path: NSBezierPath = {
    let path = NSBezierPath()
    path.lineWidth = 50.0
    path.lineJoinStyle = .roundLineJoinStyle
    path.lineCapStyle = .roundLineCapStyle
    return path
}()

enum State {
    case normal
    case drawingLine(from: CGPoint, to: CGPoint)
}
var state = State.normal

override func mouseDown(with event: NSEvent) {
    super.mouseDown(with: event)
    var lastPoint = event.locationInWindow
    lastPoint.x -= frame.origin.x
    lastPoint.y -= frame.origin.y
    state = .drawingLine(from: lastPoint, to: lastPoint)
}

override func mouseUp(with event: NSEvent) {
    if case .drawingLine(let firstPoint, _) = state {
        var newPoint = event.locationInWindow
        newPoint.x -= frame.origin.x
        newPoint.y -= frame.origin.y

        // >>>CODE ADDED BY LC<<<
        path.move(to: convert(event.locationInWindow, from: nil))
        path.line(to: firstPoint)
        needsDisplay = true
    }
}

override func draw(_ dirtyRect: NSRect) {
    if case .drawingLine(let firstPoint, let secondPoint) = state {

        // >>>CODE ADDED BY LC<<<
        NSColor.orange.set()
        path.lineWidth = 5.0
        path.stroke()
        path.line(to: firstPoint)
        path.line(to: secondPoint)
    }
}

}

一切都应该按预期运行,你将无法画出一条瓦楞线。我希望这有帮助,并随时回复以获取更多信息。