如何使NSPopover正确地按照鼠标指针并忽略鼠标事件?

MrM*_*age 5 macos cocoa appkit nswindow nspopover

我想显示一个NSPopover跟踪用户鼠标光标的信息.

为此,我使用an NSTrackingAreapositioningRectmouseMoved事件触发时更新popover .

但是,这有两个缺点:

  1. popover跟随鼠标略有延迟.如何减少此延迟以使弹出窗口更加"粘在"鼠标指针上?
  2. 当我沿着弹出方向移动鼠标指针时,mouseExited会调用跟踪区域的方法,这会导致弹出窗口"吸收"鼠标移动事件,从而mouseMoved不再触发跟踪区域的事件.如何避免弹出窗口吸收鼠标事件,或者至少保持转发这些事件?

这个问题非常类似于围绕这个NSTrackingArea怪癖的任何方式?,由于我正在使用的区别NSPopover,所以我没有什么可以继续ignoresMouseEvents下去.

man*_*ahn 2

我看了你的问题。我无法消除延迟,但如果您设置为 ,延迟可能会popover.animates减少false

错误的做法

我能够通过在另一个边框上添加新边框(并且无阴影)来解决mouseExited过度问题。被添加到透明窗口,弹出窗口被添加到原始窗口。根据透明窗口,它位于弹出窗口上方,因此它们不能相互干扰。在下面的 gif 中你可以看到我的测试结果:popoverwindowtrackingArealevel

示例 gif

这是我的一些代码:

鼠标跟踪:

override func mouseMoved(with event: NSEvent) {
    let location = self.view.convert(event.locationInWindow, from: nil)
    popover.positioningRect.origin.x = location.x
    popover.positioningRect.origin.y = location.y
}
Run Code Online (Sandbox Code Playgroud)

自定义窗口:

transparentWindow.backgroundColor = NSColor.clear
transparentWindow.isOpaque = false
transparentWindow.styleMask = .borderless
transparentWindow.makeKeyAndOrderFront(nil)
Run Code Online (Sandbox Code Playgroud)

2016 年 11 月 11 日更新

我刚刚阅读了您提供的链接中的问题。有一个窗口可以设置ignoresMouseEvents。即使NSPopover继承自NSObject,您也有一个contentViewController,它保存一个view对象,该对象保存弹出窗口window。(正如这里所解释的)

所以只需设置

popover.contentViewController?.view.window?.ignoresMouseEvents = true
Run Code Online (Sandbox Code Playgroud)

popover显示后。