2017-09-12 8 views
0

私のアプリケーションのウィンドウには3つのペインを持つsplitviewがあります。一番左のペインはビューベースのアウトラインビューをホストします。NSWindow.contentView.hittest()はNSOutlineViewのサブビューに達しません

私はそのアウトラインビューのどこかをクリックすると、クリックされた階層の一番下のサブビューを特定したいと思います。つまり、どの行、どのセル、そして最終的にどのセルのサブビュー(コントロール)がクリックされたかです。

mouseDown(with:)をホストビューコントローラでオーバーライドしようとしましたが、呼び出されませんでした。アウトラインビューが何らかの形でイベントを呼び起こしていると思っていたので、代わりに私のNSOutlineViewサブクラス自体でメソッドを直接オーバーライドすることにしました。これは機能します。

クラスMyOutlineView:NSOutlineView {

override func mouseDown(with event: NSEvent) { 
    if let view = self.window?.contentView?.hitTest(event.locationInWindow) { 
     Swift.print("\(view.className)") 
    } 
} 

...プリント:

MyModuleというしかし、そこから私はさらにアウトラインビュー自体よりも下の階層の任意に行くことができません。

MyOutlineViewは

hittest()のドキュメントは読み取ります

最も遠い指定された点を含む (自身を含む)のビュー階層内のビューの子孫、またはnilを返すこと ポイントにある場合完全に視界の外側にある。このメソッドは、NSWindowオブジェクトによって主に で使用され、 マウスダウンイベントを受け取るビューを決定します。ほとんどの場合、このメソッドを呼び出す必要はありませんが、 は、ビューオブジェクトがそのサブビューからマウスダウンイベント を隠すように、それをオーバーライドすることができます。このメソッドは隠しビューを無視します。

アウトラインビューの最上部のサブビューをテストするにはどうすればよいですか?

答えて

1

mouseDown(with:)は、コントローラではなくビューで呼び出されます。 通常、アウトラインビュー内のコントロールはmouseDownを処理します。

コントロールを見つけたい場合は、はい、-[NSTableView(NSTableViewRowHeaderSupport) hitTest:]が問題を引き起こします。回避策:行と列を取得し、セルビューを取得し、セルビューでhitTestを呼び出します。

override func mouseDown(with event: NSEvent) { 
    let localPoint = self.convert(event.locationInWindow, from: nil) 
    let column = self.column(at: localPoint) 
    let row = self.row(at: localPoint) 
    if column >= 0 && row >= 0 { 
     if let cellView = self.view(atColumn: column, row: row, makeIfNecessary: false) { 
      if let cellSuperViewPoint = cellView.superview?.convert(localPoint, from: self) { 
       if let view = cellView.hitTest(cellSuperViewPoint) { 
        Swift.print("\(view.className)") 
       } 
      } 
     } 
    } 
} 
+0

ありがとうございます。私は、https://instagram.com/p/BY-57nMFUvy/を私のアウトラインビューに適用してこのコードを修正しました。リンクされたリポジトリ_does_は、ビューコントローラ上で 'mouseDown(with:)'を使用します。 –

+0

そこにあるコメントに示唆されているように、アウトラインビューで 'validateProposedFirstResponder:forEvent:'をオーバーライドして、特定の 'NSView'サブクラスに対して' true'を返しました。 –

+0

あなたは 'mouseDown(with:)'とコントローラについて正しいです。 – Willeke

関連する問題