NSSplitView具有称为NSSplitViewDividerStyleThin的分隔线样式,这已成为OS X的最新版本的规范。它仅绘制了一个1像素宽的实线来表示分隔线。但是,分隔线的实际跟踪区域大约为3-5像素宽,从而允许用户在分隔线的任一侧单击一点以启动拖动。

由于拆分视图的子视图的布局使得它们实际上彼此之间仅相距1像素,因此拆分视图如何跟踪光标和鼠标按下事件,以便它能够截取除法器“框架”之外的任何事件”。通常,这些事件会进入基础视图(如滚动条与分隔线齐平)。

第一个想法:

NSSplitView的分隔线只有一个3-5像素宽的透明子视图,位于其两个(或多个)内容视图的顶部。但是,如果我查询splitview的子视图数,它只会返回2。同样,如果我使用F-Script之类的方法进行检查。

这个Stack Overflow问题中还讨论了AppKit确实不支持重叠的同级视图:

Is there a proper way to handle overlapping NSView siblings?

第二个想法:

也许NSSplitView只是将NSTrackingArea用作分隔线,但是如果我向拆分视图询问其跟踪区域,则不会返回任何内容。即使使用跟踪区域,父视图上的跟踪区域是否可以覆盖子视图上的跟踪区域? (例如,我假设子视图的滚动条具有优先权-但不在拆分视图中。)

第三思想:

也许NSSplitView使用的是覆盖在顶部的某种透明窗口,但是除非我在错误的位置查看,否则不会看到任何额外的窗口被创建。

第四思想:

NSSplitView正在使用本地事件监视器来跟踪发往该应用程序的所有鼠标移动和鼠标按下事件,并拦截拆分视图的跟踪区域内的任何事件,即使这些事件在技术上在子视图上也是如此。

那么NSSplitView如何能够拦截在为细边框绘制的可视1像素宽的空间之外但发生在其子视图之一上的鼠标事件?

最佳答案

首先,似乎NSSplitView覆盖了-resetCursorRects,并在该方法中使用-addCursorRect:cursor:添加了光标rect。这就是它如何安排光标在其分隔线附近进行更改。

其次,它覆盖-hitTest:。鼠标事件由-[NSWindow sendEvent:]路由到视图。它使用-hitTest:询问其视图(例如contentView和主题框架内容)是哪个后代视图被命中的。当找到命中哪个视图时,它将在该视图上调用-mouseDown:(或类似,取决于确切的事件)。因此,视图可以防止将鼠标事件路由到其子视图。即使该点实际上在其子视图之一之内,它也可以从其-hitTest:的覆盖返回自己,并且鼠标事件将传递给它而不是子视图。

关于objective-c - 使用分割隔线样式时,NSSplitView如何跟踪光标?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29487466/

10-10 00:34