2015-04-07 43 views
0

NSSplitView有一个称为NSSplitViewDividerStyleThin的分隔线样式,它已成为OS X最新版本的标准。它仅绘制一个1像素宽的实线表示分隔线。但是,分隔线的实际跟踪区域大约为3-5个像素,允许用户点击分隔线两侧的一点点来启动拖动。使用细分隔线样式时,NSSplitView如何跟踪光标?

由于拆分视图的子视图的布局使得它们实际上只相距一个像素,因此拆分视图如何跟踪光标和鼠标向下的事件,以便它能够拦截发生在分频器的“帧”。通常情况下,这些事件会进入底层视图(如滚动条与分隔线齐平)。

首先想到:

NSSplitView刚刚对于被放置在它的两个(或更多个)内容视图顶部的分频器3-5像素宽,透明子视图。但是,如果我查询splitview的子视图的数量,它只返回2.同样,如果我检查使用像F-Script的东西。

它也已经在这个堆栈溢出问题是重叠的兄弟的意见不被AppKit的真正支持的讨论:

Is there a proper way to handle overlapping NSView siblings?

思考之二:

,也许NSSplitView只是使用NSTrackingArea为分隔线,但如果我问分割视图的跟踪区域,没有返回。即使它正在使用跟踪区域,父视图上的跟踪区域是否可以覆盖子视图上的跟踪区域? (我假设一个子视图的滚动条,例如,将采取precedence-但在拆分视图不会。)

三思考:

,也许NSSplitView使用某种透明窗口这是覆盖顶部,但除非我看错了位置,我没有看到任何额外的窗口被创建。

四思想:

NSSplitView使用本地事件监控器来跟踪所有的鼠标移动和鼠标向下发往应用程序事件,并拦截任何将拆分视图的跟踪区域内,甚至如果事件技术上在子视图上。

那么NSSplitView如何能够拦截超出为薄边界绘制的可视1-像素宽空间之外的鼠标事件,而不是在其子视图之一上发生?

回答

1

首先,看起来NSSplitView覆盖了-resetCursorRects,并且在该方法中,使用-addCursorRect:cursor:来添加游标反折。这就是它如何安排光标在其分隔符附近变化的方式。其次,它覆盖了-hitTest:。鼠标事件被路由到-[NSWindow sendEvent:]。这使用-hitTest:来询问它的观点(例如contentView和主题框的东西)哪个后代观点被击中。当它发现哪个视图被击中时,它会在该视图上调用-mouseDown:(或类似的视确切事件而定)。所以,一个视图可以防止鼠标事件被路由到它的子视图。即使该点实际上位于其子视图中的一个中,并且鼠标事件将传递给它而不是子视图,它也可以从其覆盖-hitTest:的返回自身。

+0

已经使用过[[CALayer hitTest]],它甚至从来没有想到可以使用NSView的实现来覆盖否则会被返回的视图。快速测试看起来很有希望。谢谢肯。 – kennyc