如何让 NSPopover 正确跟随鼠标指针并忽略鼠标事件?
How to make NSPopover properly follow the mouse pointer and ignore mouse events?
我想显示跟踪用户鼠标光标的信息NSPopover
。
为此,每当 mouseMoved
事件触发时,我使用 NSTrackingArea
更新弹出窗口的 positioningRect
。
但是,这有两个缺点:
- 弹出窗口跟随鼠标稍有延迟。我怎样才能减少这个延迟,使弹出窗口看起来更 "glued" 到鼠标指针?
- 当我在弹出窗口的方向移动鼠标指针时,跟踪区域的
mouseExited
方法被调用,这导致弹出窗口 "absorb" 鼠标移动事件,因此跟踪区域的mouseMoved
事件不再触发。我怎样才能避免弹出窗口吸收鼠标事件,或者至少继续转发这些事件?
这个问题和Any way around this NSTrackingArea quirk?非常相似,不同的是我用的是NSPopover
,所以我没有设置ignoresMouseEvents
。
我看了你的问题。我无法消除延迟,但如果将 popover.animates
设置为 false
可能会减少延迟。
错误的做法:
我能够通过在另一个边框之上添加新边框(和无阴影)window
来解决 mouseExited
超过 popover
的问题。 trackingArea
被添加到透明window,popover到原来的。根据透明 windows level
,它位于弹出窗口上方,因此它们不会相互干扰。
在下面的 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
}
自定义window:
transparentWindow.backgroundColor = NSColor.clear
transparentWindow.isOpaque = false
transparentWindow.styleMask = .borderless
transparentWindow.makeKeyAndOrderFront(nil)
2016 年 11 月 11 日更新:
我刚刚阅读了您提供的 link 中的问题。有一个 window 可以设置 ignoresMouseEvents
。尽管 NSPopover
继承自 NSObject
,但您有一个 contentViewController
,它包含一个 view
对象,该对象包含弹出窗口 window
。 (如解释here)
所以只需设置
popover.contentViewController?.view.window?.ignoresMouseEvents = true
显示 popover
之后。
我想显示跟踪用户鼠标光标的信息NSPopover
。
为此,每当 mouseMoved
事件触发时,我使用 NSTrackingArea
更新弹出窗口的 positioningRect
。
但是,这有两个缺点:
- 弹出窗口跟随鼠标稍有延迟。我怎样才能减少这个延迟,使弹出窗口看起来更 "glued" 到鼠标指针?
- 当我在弹出窗口的方向移动鼠标指针时,跟踪区域的
mouseExited
方法被调用,这导致弹出窗口 "absorb" 鼠标移动事件,因此跟踪区域的mouseMoved
事件不再触发。我怎样才能避免弹出窗口吸收鼠标事件,或者至少继续转发这些事件?
这个问题和Any way around this NSTrackingArea quirk?非常相似,不同的是我用的是NSPopover
,所以我没有设置ignoresMouseEvents
。
我看了你的问题。我无法消除延迟,但如果将 popover.animates
设置为 false
可能会减少延迟。
错误的做法:
我能够通过在另一个边框之上添加新边框(和无阴影)window
来解决 mouseExited
超过 popover
的问题。 trackingArea
被添加到透明window,popover到原来的。根据透明 windows level
,它位于弹出窗口上方,因此它们不会相互干扰。
在下面的 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
}
自定义window:
transparentWindow.backgroundColor = NSColor.clear
transparentWindow.isOpaque = false
transparentWindow.styleMask = .borderless
transparentWindow.makeKeyAndOrderFront(nil)
2016 年 11 月 11 日更新:
我刚刚阅读了您提供的 link 中的问题。有一个 window 可以设置 ignoresMouseEvents
。尽管 NSPopover
继承自 NSObject
,但您有一个 contentViewController
,它包含一个 view
对象,该对象包含弹出窗口 window
。 (如解释here)
所以只需设置
popover.contentViewController?.view.window?.ignoresMouseEvents = true
显示 popover
之后。