如何用两次鼠标单击编码绘制直线(OSX Mac App)? [英] How to code drawing a straight line with two mouse clicks (OSX Mac App)?

查看:135
本文介绍了如何用两次鼠标单击编码绘制直线(OSX Mac App)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个简单的绘图应用程序(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
    }

干杯!

解决方案

我了解您要在这里实现的目标!因此,我在andyvn22的解决方案中添加了几行代码,这些代码行将对您的工作有所帮助,请注意:为简单起见,请启动一个新的"Xcode项目",我们可以确保所有内容都涵盖在一起.

在新项目中,右键单击"ViewController.swift"并添加新文件...选择可可类",然后单击下一步",将此文件命名为"DrawingView",确保以下子类为:"NSView",然后选择下一步".

>

现在完成操作,可以设置您的界面,输入"Main.storyboard"并拖放自定义视图",确保根据您的喜好添加约束.现在,在选择自定义视图"后输入身份检查器",然后在顶部的类"中添加"DrawingView".

我希望这已经很合理了!确定,打开助手编辑器",以便您可以同时查看"ViewController.swift"和"Main.storyboard",右键单击并将其从自定义视图"拖动到"ViewController.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)
        }
    }
}

一切都应按预期运行,您将无法绘制虚线.希望这对您有所帮助,您可以随时回复以获取其他信息.

I'm trying to make a simple drawing app (OSX Mac app) and I'm trying to figure out how the user can draw a line by two mouse clicks, for example, the first mouse click (mouseDown then mouseUP) would mark the origin point of the line, and the second mouse click (mouseDown then mouseUP) would mark the end point of the line. Before the user makes the second click of the end point, I'd like the line (before anchoring the end point) to be shown live, kind of like in photoshop. Both Objective-C and Swift are fine.

So far I've got...

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
    }

Cheers!

解决方案

I understand what you are attempting to achieve here! So I have added lines of code to the andyvn22's solution that should assist your endeavours, please note: for simplicity purposes start a new 'Xcode Project' and we can make sure everything is covered together.

In your new project Right Click 'ViewController.swift' and add New File... Select 'Cocoa Class' and Click Next, name this file 'DrawingView' assure Subclass of: is 'NSView' and select Next.

Now your finished that lets setup your interface, enter 'Main.storyboard' and drag/drop a 'Custom View' make sure to add constrains according to your preferences. Now enter your 'Identity Inspector' while 'Custom View' is selected and add 'DrawingView' to Class at the top.

I hope this is making sense soo far! Ok open 'Assistant Editor' so you can view 'ViewController.swift' and 'Main.storyboard' simultaneously, Right Click and drag from 'Custom View' to 'ViewController.swift', name this 'draw' and select connect.

You will notice Xcode has automatically updated @IBOutlet to your Subclass, and your 'ViewController.swift' looks like the example below.

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.
        }
    }
}

Now select the 'DrawingView.swift' file and clear all content on page, highlight the code below, copy and paste into your project.

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)
        }
    }
}

Everything should be running as intended, you will be incapable of drawing a crocked line. I hope this has helped and feel free to reply for additional information.

这篇关于如何用两次鼠标单击编码绘制直线(OSX Mac App)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆