NSMenu willClose 通知可能吗?

Is NSMenu willClose notitfication possible?

NSMenu 对象是否可以在关闭之前而不是之后进行通知?它的委托有方法 didClose(_:) 但我想在它实际关闭之前更新它的项目,因为消失的动画太长并且眼睛可以看到变化。

我试过监视 NSEvents,但没有用,因为 NSMenu 没有 public 属性 包含它的 NSWindow 对象。

理论上可以通过为每个菜单项创建自定义 NSView 来实现。但我不喜欢这样,因为那样我就得画所有的项目图,包括选择和点击动画。

更新: 我尝试将 NSPopUpButton 子类化以跟踪菜单更新:

class CustomPopUpButton: NSPopUpButton {
    var isMenuShown: Bool = false
    var onClosingMenu: ((NSMenu)->())?
    
    override var needsDisplay: Bool {
        willSet {
            if let menu = self.menu, isMenuShown, newValue {
                onClosingMenu?(menu)
                isMenuShown = false
            }
        }
    }

    override func willOpenMenu(_ menu: NSMenu, with event: NSEvent) {
        isMenuShown = true
        super.willOpenMenu(menu, with: event)
    }
}

我对那段代码并不感到自豪,但它总体上是有效的。然而 'onClosingMenu' 方法在菜单关闭动画完成后立即被调用。之前没有。

我想要实现的视频:https://drive.google.com/file/d/1GAceKp-fTlurxSybdB3h0epVZrtQjthm/view?usp=sharing

终于,我找到了解决方案。在按钮菜单关闭之前无需与系统打交道并更新内容。我找到了另一种方法,它很简单。

我已经子class编辑了 NSPopUpButton 并在子class 中创建了另一个 NSMenu,名为 'attributedMenu'。覆盖了处理菜单项(插入和删除)的 NSPopUpButton 的所有属性,并将该操作重定向到 'attributedMenu' 属性.

NSPopUpButton 的初始菜单 属性 我仅用于 selected 项目,立即删除 non-selected 项目。

我拦截了点击按钮显示'attributedMenu',而不是class的默认菜单。

如果我 select 多个元素,该解决方案甚至可以显示 'multiple values' 标题。就像在 Apple Pages 的字体选择器中,当您 select 使用多种字体编写文本时。只需添加一个标题为 'Multiple Values' 的 NSMenuItem 并调用 super 到 select 它。

就是这样,现在它与 Apple Pages 字体选择器按钮一样完美。只要我不触及 NSPopUpButton class.

的原始 'menu' 属性

更新

已将子class上传到GitHub:https://github.com/CineDev/AttributedPopUpButton