目标c - 如何编写用两次鼠标单击绘制直线的代码(OSX Mac App)



我正在尝试制作一个简单的绘图应用程序(OSX Mac 应用程序),我正在尝试弄清楚用户如何通过两次鼠标单击来绘制线条,例如,第一次鼠标单击(鼠标按下然后鼠标向上)将标记线的原点,第二次鼠标单击(鼠标向下然后鼠标向上)将标记线的终点。在用户第二次单击终点之前,我希望该行(在锚定终点之前)实时显示,有点像在 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
    }

干杯!

具有关联值的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`
    }
}

我明白你在这里想要实现的目标!因此,我在 andyvn22 的解决方案中添加了几行代码,可以帮助您完成工作,请注意:为了简单起见,开始一个新的"Xcode 项目",我们可以确保所有内容都涵盖在一起。

在您的新项目中,右键单击"视图控制器.swift"并添加新文件...选择"Cocoa 类"并单击"下一步",将此文件命名为"绘图视图",确保子类为:"NSView",然后选择"下一步"。

现在您完成了设置界面,输入"Main.storyboard"并拖放"自定义视图",确保根据您的喜好添加约束。现在,在选择"自定义视图"时输入"身份检查器",并将"绘图视图"添加到顶部的"类"。

我希望到目前为止这是有意义的!好的,打开"助理编辑器",以便您可以同时查看"视图控制器.swift"和"主故事板",右键单击并从"自定义视图"拖动到"视图控制器.swift",将其命名为"绘制"并选择连接。

你会注意到 Xcode 已经自动更新了@IBOutlet到你的子类,你的"ViewController.swift"看起来像下面的例子。

import Cocoa
class 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"文件并清除页面上的所有内容,突出显示下面的代码,复制并粘贴到您的项目中。

import Cocoa
class 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)
        }
    }
}

一切都应该按预期运行,您将无法画出一条混乱的线。我希望这有所帮助,并随时回复更多信息。

最新更新