我的应用程序窗口有一个带有三个窗格的splitview;最左边的窗格包含基于视图的大纲视图。
当我单击该大纲视图上的某个位置时,我想确定所单击的层次结构中最底部的子视图。也就是说,单击了哪一行,哪个单元格,以及最终单击了哪个子视图(控件)。
我尝试在托管视图控制器上覆盖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对象确定应该接收哪个视图 鼠标按下事件。您很少需要调用此方法,但是您 可能希望覆盖它以使视图对象隐藏鼠标按下事件 从它的子视图。此方法忽略隐藏的视图。
如何点击测试大纲视图的最顶层子视图?
答案 0 :(得分: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)")
}
}
}
}
}