Я хочу добавить NSMenuItem с этим кодом:
import Cocoa
class MyTestAppClass {
var closure: () -> Void
init(closure: @escaping () -> Void) {
self.closure = closure
}
@objc func invoke () {
closure()
}
}
let myTestAppClass: MyTestAppClass = MyTestAppClass(closure: { print("Hello, world!") })
class AppDelegate: NSObject, NSApplicationDelegate {
private var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
buildMainMenu()
buildWindow()
}
private func buildMainMenu() {
let appMainMenu: NSMenu = NSMenu()
let mainMenu: NSMenuItem = NSMenuItem()
mainMenu.submenu = NSMenu(title: "MainMenu")
let mainMenuItem0 = NSMenuItem(title: "Test", action: #selector(myTestAppClass.invoke), keyEquivalent: "t")
mainMenu.submenu?.items = [mainMenuItem0]
appMainMenu.items = [mainMenu]
NSApp.mainMenu = appMainMenu
}
private func buildWindow() {
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 100.0, height: 100.0),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.center()
window.setFrameAutosaveName("Main Window")
window.title = "No Storyboard Window"
window.makeKeyAndOrderFront(window)
}
}
Xcode добавляет мой элемент в меню, но он не активен, он серый и отключен. Как я могу решить проблему, Xcode даже не показывает мне ошибку. Я пытался использовать objc_setAssociatedObject, но не смог правильно использовать его для решения проблемы, я не пытаюсь добавить расширение или любую другую функцию в NSMenu для решения проблемы, я хочу иметь более общий ответ для применения к любому представлению, которому нужен селектор , например кнопки или другие вещи.
Целевой класс должен наследоваться от NSObject, и вы должны явно указать цель пункта меню. И экземпляр MyTestAppClass должен быть в другом классе.
@Alexander NSMenuItem использует шаблон цель/действие. Вы можете установить цель. Если цель nil, то она переходит в цепочку респондентов.
@Willeke, о, интересно, action доступен как свойство, просто это не один из параметров инициализатора. Странный. Не беспокойся в таком случае
Пожалуйста, не создавайте дубликаты аккаунтов, Милен stackoverflow.com/q/75348877/3141234
В вашей демонстрации есть пара ошибок:
Следующий исходный код должен работать в Xcode, если вы создаете быстрый проект и удаляете предварительно предоставленный код AppDelegate, копируете/вставляете следующий код на его место и изменяете имя «AppDelegate.swift» на «main.swift»:
import Cocoa
class MyTestAppClass {
var closure: () -> Void
init(closure: @escaping () -> Void) {
self.closure = closure
}
@objc func invoke() {
closure()
}
}
let myTestAppClass: MyTestAppClass = MyTestAppClass(closure: { print("Hello, world!") })
class AppDelegate: NSObject, NSApplicationDelegate {
var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
buildMainMenu()
buildWindow()
}
func buildMainMenu() {
let appMainMenu: NSMenu = NSMenu()
let mainMenu: NSMenuItem = NSMenuItem()
mainMenu.submenu = NSMenu(title: "MainMenu")
let mainMenuItem0 = NSMenuItem(title: "Test", action: #selector(myTestAppClass.invoke), keyEquivalent: "t")
mainMenuItem0.target = myTestAppClass
mainMenu.submenu?.items = [mainMenuItem0]
appMainMenu.items = [mainMenu]
NSApp.mainMenu = appMainMenu
}
func buildWindow() {
window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 100.0, height: 100.0), styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], backing: .buffered, defer: false)
window.center()
window.setFrameAutosaveName("Main Window")
window.title = "No Storyboard Window"
window.makeKeyAndOrderFront(window)
}
}
let appDelegate = AppDelegate()
// **** Main **** //
let application = NSApplication.shared
application.delegate = appDelegate
application.run()
Я попробовал ваш данный код и посмотрел на мой данный код, о котором идет речь, единственная недостающая часть была mainMenuItem0.target = myTestAppClass, почему мне нужно добавить (_ sender:AnyObject) для вызова функции, поскольку коды работают и без нее, что касается основного файла, я предполагаю, что любой человек, который может ответить в этом вопросе можно разобраться без упоминания о нем в вопросе. Кстати, спасибо за вашу помощь, мне просто нужно знать, зачем мне нужен (_ sender:AnyObject) в моем коде?
Они продолжают менять быстрый язык. Раньше мне приходилось его использовать, но, похоже, вы правы, что сейчас он нам не нужен. Я пересмотрю свой ответ. Спасибо за продолжение.
Спасибо, я не могу голосовать, потому что я новичок, вы хорошо поработали!
Ах, я думаю, что это основано на моем комментарии к вашему предыдущему вопросу. Похоже, что NSMenuItem не совсем использует шаблон цель/действие, поскольку вы не можете установить цель, это всегда цепочка ответчика. Вы можете сделать эти объекты частью цепочки респондентов, но это было бы странно и привередливо. Я думаю, вам лучше просто использовать обычные методы @objc для ваших представлений, делегата приложения и т. д., которые уже участвуют в цепочке респондентов.