NSPopUpButton - 使用 Cocoa 绑定填充动态内容时的奇怪行为

NSPopUpButton - Weird behavior when populating dynamic content with Cocoa Binding

我正在尝试创建一个带有动态内容的 NSPopUpButton,这是我的设计:

+-------------+
| None        | <-- Static
| Last Item   | <-- Static
|-------------| <-- Separator
| History:    | <-- Dynamic: "History:" / "No History"
| ...         | <-- Dynamic
+-------------+

这是我的 ViewController.swift 代码:

class ViewController: NSViewController, NSMenuDelegate {

    @objc dynamic var contents: [String] = ["None", "Last Item", ""]
    @objc dynamic var selectedIndex: Int = 0

    func updateContent() {
        // update contents array
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        updateContent()
        // other code
    }

    func menuNeedsUpdate(_ menu: NSMenu) {
        for (index, item) in menu.items.enumerated() {
            if item.title == "" {
                menu.items[index] = .separator()
            } else if item.title == "History:" || item.title == "No History" {
                menu.items[index].isEnabled = false
            }
        }
    }

    func menuDidClose(_ menu: NSMenu) {
        print(selectedIndex)
    }
}

我用界面生成器做了 Cocoa 绑定。我的NSPopUpButtonContent Values绑定到属性,contentsSelected Index绑定到selectedIndex。我将 ViewController 对象设置为 NSPopUpButton 的嵌入式 NSMenu.

的委托

因此,NSPopUpButton 的内容没有问题,但它会检查 NSPopUpButton 中我 select 的任何项目,即使我 select ] 别的,最后变成这样:

而且如果我打开菜单 (NSPopUpButton) 并通过不 select 菜单中的任何项目(单击菜单以外的任何地方)直接关闭它,它会自动 select 是第一个项目 ("None"),与之前 select 编辑的项目无关。

然后,我决定在通过实施 menuDidClose(_:) 关闭菜单后监视 selectedIndex 的值,结果 selectedIndex 正是我之前 select 编辑的(哪个是正确的)。 即使我删除了 selectedIndex.

的绑定,这个问题仍然存在

这真的很奇怪,没有任何意义。谁能解释这是怎么回事?我怎样才能正确地使用静态和动态内容的混合填充 NSPopUpButton

问题是由 menu.items[index] = .separator() 引起的。它取代了菜单的项目数组。弹出按钮的itemArray属性指向菜单的item数组,这个属性没有调整。弹出按钮找不到关闭复选标记的菜单项。将菜单项替换为

menu.removeItem(at: index)
menu.insertItem(NSMenuItem.separator(), at: index)

或者在 IB 的菜单中放置一个分隔项,然后使用绑定的 Content Placement Tag 设置将绑定项插入分隔项下方。