Я пытаюсь создать 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
, и оставляет их отмеченными, даже если я выбираю что-то еще, в конечном итоге это становится примерно таким:
А также, если я открываю меню (NSPopUpButton
) и напрямую закрываю его, не выбирая ни один элемент в меню (щелкнув в любом месте, кроме меню), он автоматически выбирает первый элемент («Нет») независимо от предыдущего выбранный элемент.
Затем я решил отслеживать значение для selectedIndex
после закрытия меню, реализовав menuDidClose(_:)
, и оказалось, что selectedIndex
- это именно то, что я выбрал ранее (что правильно). Эта проблема сохраняется даже после того, как я удалил привязку для selectedIndex
.
Это действительно странно и бессмысленно. Кто-нибудь может объяснить, что с этим происходит? И как я могу правильно заполнить NSPopUpButton
смесью статического и динамического содержимого?
1 ответ
Проблема вызвана menu.items[index] = .separator()
. Он заменяет массив элементов меню. Свойство itemArray
всплывающей кнопки указывает на массив элементов меню, и это свойство не регулируется. Всплывающая кнопка не может найти пункт меню, чтобы снять галочку. Замените пункт меню на
menu.removeItem(at: index)
menu.insertItem(NSMenuItem.separator(), at: index)
Или поместите разделитель в меню в IB и используйте Тег размещения контента настройка привязки для вставки связанных элементов под элементом-разделителем.
Похожие вопросы
Новые вопросы
swift
Swift - это безопасный, быстрый и выразительный язык программирования общего назначения, разработанный Apple Inc. для своих платформ и Linux. Swift с открытым исходным кодом. Используйте тег только для вопросов о языковых функциях или необходимости кода в Swift. Используйте теги [ios], [ipados], [macos], [watch-os], [tvos], [cocoa-touch] и [cocoa] для (не зависящих от языка) вопросов о платформах или фреймворках.