2016-07-06 17 views
0

私は単純な描画アプリケーション(OSX Mac app)を作ろうとしています。ユーザーが2回のマウスクリックで線を描く方法を理解しようとしています。たとえば、最初のマウスクリック(mouseDown then mouseUP)線の原点をマークし、2回目のマウスクリック(mouseDownとmouseUP)は、線の終点をマークします。ユーザーがエンドポイントの2回目のクリックを行う前に、(エンドポイントを固定する前の)ラインをPhotoshopのようにライブで表示することをお勧めします。 Objective-CとSwiftの両方が問題ありません。2回のマウスクリックで直線を描く方法(OSX Mac App)?

これまでのところ、私が持っている

...

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

バイナリステートマシン 'var gotFirstPoint = false'を使用し、' false'をmouseClickに設定し、原点を保存し、mouseMoveの値をチェックし、 'true'を再描画し、' true'ならmouseClickで確定します。 ? – Grimxn

+0

これまではドラッグして線を描くことができますが、ドラッグしている間も線は見えません。私は、私がライブで上映されるようにドラッグしているラインを欲しいです。 – sundrius

+0

mouseMoveルーチンでは、エンドポイントをキャプチャしてビューの 'needsDisplay'を設定し、' drawRect'に現在ドラッグしているかどうかをチェックし、そうであれば描画します。完全にうまくいくはずです... – Grimxn

答えて

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` 
    } 
} 
+0

お返事ありがとうございましたandyvn22。私はあなたのコードを試しましたが、私はそれを動作させることができませんでした。コードは本当に素晴らしいように見えますが、私はまだ初心者ですから、これについて私が助けてくれるかどうか疑問に思っていましたか?乾杯! – sundrius

+0

問題はありません - 何が問題になっているのかを特定できれば、それについて新しい質問をすることができます(上書きした 'draw(_ :)'で線を描く方法ですか? – andyvn22

0

私はあなたがここで達成しようとしていることを理解しています!だから私はあなたの努力を助けるべきであるandyvn22のソリューションに一連のコードを追加しました。簡単にするために、新しい「Xcodeプロジェクト」を開始し、すべてが一緒にカバーされていることを確認することができます。

新しいプロジェクトで 'ViewController.swift'を右クリックし、新しいファイルを追加... 'Cocoa Class'を選択し、次へをクリックします。このファイルに 'DrawingView'という名前を付けます:Subclass of: 'NSView'を選択し、

これで、インターフェイスをセットアップし、 'Main.storyboard'を入力し、「カスタムビュー」をドラッグ&ドロップすると、設定に応じて制約を追加することができます。 'Custom View'が選択されている間にあなたの 'Identity Inspector'を入力し、一番上のClassに 'DrawingView'を追加します。

これが意味をなさないことを望みます。 [Assistant Editor]を開き、 'ViewController.swift'と 'Main.storyboard'を同時に表示することができます。右クリックして 'Custom View'から 'ViewController.swift'にドラッグし、名前を 'draw'にして接続を選択します。

Xcodeが自動的に@IBOutletをサブクラスに更新し、 'ViewController.swift'が下の例のように表示されます。

輸入ココア

クラスの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' ファイルを選択し、ページ上のすべてのコンテンツをクリアし、次のコードを強調表示し、コピーして、プロジェクトに貼り付けます。

輸入ココア

クラス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) 
    } 
} 

}

意図したとおりにすべてが動作している必要があり、あなたはcrocked線を引くことができないだろう。私はこれが助けてくれると嬉しく思います。

関連する問題