丰富的、类似窗口的上下文菜单(如 Interface Builder)
Posted
技术标签:
【中文标题】丰富的、类似窗口的上下文菜单(如 Interface Builder)【英文标题】:Rich, Window-like Context Menu (like Interface Builder) 【发布时间】:2017-08-18 06:57:55 【问题描述】:我需要一个上下文菜单,它的功能类似于 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
...但感觉就像 hack;我通过假装关心呈现一个实际的NSMenu
(即覆盖一个方法)来欺骗系统放弃右(控制)单击事件的时间明确地打算这样做),但利用这个时机来做不同的事情。
当用户点击其他地方时,我还需要放置一些逻辑来关闭窗口(上下文菜单内置了此功能)。
我认为子类化NSMenu
和NSMenuItem
以获得上述行为和外观也不可行......
有更好的方法吗? 有人知道(或能够猜到)Interface Builder 的实际作用吗?
编辑: 正如@Willeke 在评论中指出的那样,面板显示的条件与上下文菜单并不完全相同,因此它肯定不是一个。这意味着为了显示窗口而劫持上述方法不仅不优雅,而且是错误的。问题涉及如何显示窗口(即检测静态、非拖动右键单击)。
【问题讨论】:
如果它看起来像一个窗口并且表现得像一个窗口,那么它很可能是一个窗口。它出现在右键单击和控制单击上。与上下文菜单不同,它不会在右拖动或控制拖动时立即出现。它与菜单没有任何关系。 @Willeke 谢谢;我也有同样的怀疑。问题仍然在于如何触发窗口的外观。根据您指出的关于右键拖动的差异,它看起来越来越像劫持menu(for:)
是错误的方法......
【参考方案1】:
您需要从视图子类中覆盖rightMouseDown(with:)
并使用它来触发显示面板。 NSView's implementation of that method 是调用 menu(for:)
并显示返回的菜单,因此您的自定义子类可以使用它来显示其自定义菜单面板,而不是调用 super。
为了与标准上下文菜单和 Interface Builder 中的菜单完全一致,您还需要通过覆盖 mouseDown(with:)
来处理 ctrl-left-clicks 并检查事件的 modifierFlags
是否包含 .control
。
【讨论】:
以上是关于丰富的、类似窗口的上下文菜单(如 Interface Builder)的主要内容,如果未能解决你的问题,请参考以下文章