我正在尝试制作一个简单的绘图应用程序(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
}
干杯!
答案 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)
}
}
}
一切都应该按预期运行,你将无法画出一条瓦楞线。我希望这有帮助,并随时回复以获取更多信息。