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 绑定。我的NSPopUpButton
的Content Values
绑定到属性,contents
,Selected 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 设置将绑定项插入分隔项下方。
我正在尝试创建一个带有动态内容的 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 绑定。我的NSPopUpButton
的Content Values
绑定到属性,contents
,Selected 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 设置将绑定项插入分隔项下方。