我正面临一个奇怪的情况。我有NSMenu
一个子菜单。子菜单的内容以编程方式填充。在我的validateMenuItem:
方法中,我可以看到所有正在检查的项目(父项目)以及子项目(一旦我单击子菜单),除了那些在我的自动填充子菜单中的项目。
这是为什么?难道我做错了什么?关于如何解决这个问题的任何想法?
我正面临一个奇怪的情况。我有NSMenu
一个子菜单。子菜单的内容以编程方式填充。在我的validateMenuItem:
方法中,我可以看到所有正在检查的项目(父项目)以及子项目(一旦我单击子菜单),除了那些在我的自动填充子菜单中的项目。
这是为什么?难道我做错了什么?关于如何解决这个问题的任何想法?
这是解决方案:
CocoavalidateMenuItem:
在 Class 中查找NSMenuItem
动作选择器所在的方法。
因此,如果您NSMenuItem
的操作选择器(例如@selector(someSelector:)
)是在 中实现的,那么如果您想验证相应的菜单项,请SomeClass
确保您也有一个validateMenuItem:
方法。SomeClass
@Dr.Kameleon 有正确的答案。
如果可以的话,我会添加一个小点来更新它?我的代码最近在这方面发生了故障,并且在之前工作时停止调用 validateMenuItem:。我没有注意到,因为唯一的症状是一个菜单项在它应该被禁用时不再被禁用。
问题是 Swift 4。该方法必须归因于 @objc。在早期版本的 Swift 中,从 NSObject、NSViewController 等继承就足够了,但是随着 Swift 4 和 5 的新版本发生了变化。
ps 将方法放在扩展中似乎很好。
以上答案并没有帮助我解决我的问题。我创建了一个单独的项目来了解何时validateMenuItem(:)
调用该方法。
validateMenuItem(:)
只有在以下情况下才会调用该方法:
NSMenuItemValidation
在实现NSPopUpButton
.NSMenuItemValidation
协议的对象设置一个动作和目标。validateMenuItem(:
) 方法。dummyAction(:)
不做任何事情的 NSMenuItem 方法。版本 11.5 (11E608c),Swift 5.0,DP:macOS 10.15。
代码:
import Cocoa
// 1) Conform to NSMenuItemValidation in the class which implements the NSPopUpButton.
class NSMenuItemValidationTestViewController: NSViewController, NSMenuItemValidation {
@IBOutlet weak var popupButton: NSPopUpButton!
// MARK: - ViewController lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// .target and .action are set programmatically because menus are mostly build programmatically.
// 2) All NSMenuItems must have an action and target set to the object which implements the
// NSMenuItemValidation protocol.
self.popupButton?.menu?.items.forEach{( $0.target = self )}
self.popupButton?.menu?.items.forEach{( $0.action = #selector(dummyAction(_:)) )}
}
// MARK: - NSMenuItemValidation
// 3) Implement the validateMenuItem(:) method.
func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
print("Function: \(#function), line: \(#line)")
return true
}
// 4) Implement the dummyAction(:) method for NSMenuItem which doesn't do anything
@IBAction func dummyAction(_ sender: NSMenuItem?) {
print("Function: \(#function), line: \(#line)") }
}
// 5) The NSPopUpButton "Items: Autoenables" checkbox must be set to true in storyboard.
// or
// self.popupButton?.menu?.autoenablesItems = true
TODO:Github 链接到源代码。(快来了)。