丰富的 Window-like 上下文菜单(如 Interface Builder)
Rich, Window-like Context Menu (like Interface Builder)
我需要一个上下文菜单,其功能类似于 Interface Builder 在右键(控制)单击视图、视图控制器等时显示的菜单:
乍一看,它看起来像一个 NSPanel
,其样式属性设置为 "HUD Panel",包含某种大纲视图。
window 本身应该不难实现,但在右键(控制)单击时显示上下文菜单的通常方法是重写方法:
func menu(for event: NSEvent) -> NSMenu?
...将 NSMenu
作为 return 值;不能传递 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
}
...但感觉像是 hack;我通过 假装关心 呈现实际 [=14] 来欺骗系统放弃右(控制)-click 事件的 时间 =](即,重写明确用于此的方法),但使用该时间做不同的事情。
我还需要放置一些逻辑来在用户单击其他地方时关闭 window(上下文菜单内置了此功能)。
我认为子类化 NSMenu
和 NSMenuItem
来获得上述行为和外观也不可行...
有没有更好的方法?
有人知道(或能够猜到)Interface Builder 实际做什么吗?
编辑: 正如@Willeke 在评论中指出的那样,要显示的面板的条件与上下文菜单不完全相同,所以它肯定是不是一个。这意味着劫持上述方法以显示 window 不仅不优雅,而且是错误的。问题是关于 如何显示 Window(即检测静态、非拖动右键单击)。
您需要从您的视图子类中覆盖 rightMouseDown(with:)
并使用它来触发显示面板。 NSView's implementation of that method 调用 menu(for:)
并显示返回的菜单,因此您的自定义子类可以使用它来显示其自定义菜单面板,而不是调用 super.
为了与标准上下文菜单和 Interface Builder 中的菜单在行为上完全一致,您还需要通过覆盖 mouseDown(with:)
来处理 ctrl-left-clicks 并检查事件是否 modifierFlags
包括 .control
.
我需要一个上下文菜单,其功能类似于 Interface Builder 在右键(控制)单击视图、视图控制器等时显示的菜单:
乍一看,它看起来像一个 NSPanel
,其样式属性设置为 "HUD Panel",包含某种大纲视图。
window 本身应该不难实现,但在右键(控制)单击时显示上下文菜单的通常方法是重写方法:
func menu(for event: NSEvent) -> NSMenu?
...将 NSMenu
作为 return 值;不能传递 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
}
...但感觉像是 hack;我通过 假装关心 呈现实际 [=14] 来欺骗系统放弃右(控制)-click 事件的 时间 =](即,重写明确用于此的方法),但使用该时间做不同的事情。
我还需要放置一些逻辑来在用户单击其他地方时关闭 window(上下文菜单内置了此功能)。
我认为子类化 NSMenu
和 NSMenuItem
来获得上述行为和外观也不可行...
有没有更好的方法? 有人知道(或能够猜到)Interface Builder 实际做什么吗?
编辑: 正如@Willeke 在评论中指出的那样,要显示的面板的条件与上下文菜单不完全相同,所以它肯定是不是一个。这意味着劫持上述方法以显示 window 不仅不优雅,而且是错误的。问题是关于 如何显示 Window(即检测静态、非拖动右键单击)。
您需要从您的视图子类中覆盖 rightMouseDown(with:)
并使用它来触发显示面板。 NSView's implementation of that method 调用 menu(for:)
并显示返回的菜单,因此您的自定义子类可以使用它来显示其自定义菜单面板,而不是调用 super.
为了与标准上下文菜单和 Interface Builder 中的菜单在行为上完全一致,您还需要通过覆盖 mouseDown(with:)
来处理 ctrl-left-clicks 并检查事件是否 modifierFlags
包括 .control
.