丰富的,类似窗口的上下文菜单(如Interface Builder)

时间:2017-08-18 06:57:55

标签: macos cocoa interface-builder contextmenu

我需要一个上下文菜单,其功能与Interface Builder在视图,视图控制器等上单击右键(控制)时所呈现的功能相似:

enter image description here

乍一看,它看起来像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(即,覆盖一种明确用于该方法的方法,但使用该时间来做不同的东西

当用户点击其他地方时,我还需要放置一些逻辑来关闭窗口(上下文菜单内置了此功能)。

我不认为继承NSMenuNSMenuItem以获得上述行为和外观也不可行......

有更好的方法吗? 有人知道(或能够猜测)Interface Builder实际做了什么吗?

编辑:正如@Willeke在评论中指出的那样,显示面板的条件与上下文菜单并不完全相同,所以它肯定不是一个。这意味着为了显示窗口而劫持上述方法不仅不优雅,而且是错误的。问题代表如何显示窗口(即检测静态,非拖动右键单击)。

1 个答案:

答案 0 :(得分:1)

您需要覆盖视图子类中的rightMouseDown(with:)并使用它来触发显示面板。 NSView's implementation of that method调用menu(for:)并显示返回的菜单,因此您的自定义子类可以使用它来显示其自定义菜单面板,而不是调用super。

要获得标准上下文菜单和Interface Builder中菜单的完全行为一致性,您还需要通过覆盖mouseDown(with:)来处理ctrl-left-clicks,并检查事件的modifierFlags是否包含.control