Я пытаюсь создать 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)
    }
}

Я сделал привязки какао с помощью конструктора интерфейсов. Мой NSPopUpButton Content Values привязан к свойству contents, Selected Index привязан к selectedIndex. Я установил объект ViewController как делегат для встроенного NSMenu NSPopUpButton.

Итак, с контентом NSPopUpButton проблем нет, но он проверяет любой элемент, который я выбираю в NSPopUpButton, и оставляет их отмеченными, даже если я выбираю что-то еще, в конечном итоге это становится примерно таким:

Unexpected multiple selections with NSPopUpButton

А также, если я открываю меню (NSPopUpButton) и напрямую закрываю его, не выбирая ни один элемент в меню (щелкнув в любом месте, кроме меню), он автоматически выбирает первый элемент («Нет») независимо от предыдущего выбранный элемент.

Automatically selected 'None' item

Затем я решил отслеживать значение для selectedIndex после закрытия меню, реализовав menuDidClose(_:), и оказалось, что selectedIndex - это именно то, что я выбрал ранее (что правильно). Эта проблема сохраняется даже после того, как я удалил привязку для selectedIndex.

Это действительно странно и бессмысленно. Кто-нибудь может объяснить, что с этим происходит? И как я могу правильно заполнить NSPopUpButton смесью статического и динамического содержимого?

1
AgentBilly 4 Окт 2019 в 11:51

1 ответ

Лучший ответ

Проблема вызвана menu.items[index] = .separator(). Он заменяет массив элементов меню. Свойство itemArray всплывающей кнопки указывает на массив элементов меню, и это свойство не регулируется. Всплывающая кнопка не может найти пункт меню, чтобы снять галочку. Замените пункт меню на

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

Или поместите разделитель в меню в IB и используйте Тег размещения контента настройка привязки для вставки связанных элементов под элементом-разделителем.

0
Willeke 4 Окт 2019 в 12:55