我需要一个上下文菜单,其功能与Interface Builder在视图,视图控制器等上单击右键(控制)时所呈现的功能相似:
乍一看,它看起来像NSPanel
,其样式属性设置为“HUD面板”,包含某种轮廓视图。
窗口本身应该不难实现,但在右侧(控制)单击上显示上下文菜单的常用方法是覆盖方法:
func menu(for event: NSEvent) -> NSMenu?
...以NSMenu
作为返回值;无法通过NSWindow
/ NSPanel
。
也许我可以这样做:
override func menu(for event: NSEvent) -> NSMenu? {
// Create our popup window (HUD Panel) and present it
// at the location of event:
// (...actual code omitted...)
// Prevent any actual menu from being displayed:
return nil
}
...但感觉就像是黑客;我正在欺骗系统通过假装关心来提供正确({控制) - 点击事件的时间关于呈现实际的NSMenu
(即,覆盖一种明确用于该方法的方法,但使用该时间来做不同的东西。
当用户点击其他地方时,我还需要放置一些逻辑来关闭窗口(上下文菜单内置了此功能)。
我不认为继承NSMenu
和NSMenuItem
以获得上述行为和外观也不可行......
有更好的方法吗? 有人知道(或能够猜测)Interface Builder实际做了什么吗?
编辑:正如@Willeke在评论中指出的那样,显示面板的条件与上下文菜单并不完全相同,所以它肯定不是一个。这意味着为了显示窗口而劫持上述方法不仅不优雅,而且是错误的。问题代表如何显示窗口(即检测静态,非拖动右键单击)。
答案 0 :(得分:1)
您需要覆盖视图子类中的rightMouseDown(with:)
并使用它来触发显示面板。 NSView's implementation of that method调用menu(for:)
并显示返回的菜单,因此您的自定义子类可以使用它来显示其自定义菜单面板,而不是调用super。
要获得标准上下文菜单和Interface Builder中菜单的完全行为一致性,您还需要通过覆盖mouseDown(with:)
来处理ctrl-left-clicks,并检查事件的modifierFlags
是否包含.control
。