swift - Swift + NSMenuItem 中带有参数的 Selector()

标签 swift macos swift3 nsmenu nsmenuitem

我目前正在尝试将钥匙串(keychain)中的所有键列为 NSMenuItems,当我单击其中一个键时,我希望它调用带有字符串参数的函数,但是 使用我当前的代码,当我运行我的应用程序时,每个键都会被删除,而不仅仅是我点击的键。

这是我当前的代码:

NSApplicationMain

class AppDelegate: NSObject, NSApplicationDelegate {

   let menu = NSMenu()
   let internetKeychain = Keychain(server: "example.com", protocolType: .https, authenticationType: .htmlForm)

  func applicationDidFinishLaunching(_ aNotification: Notification) {
    for key in internetKeychain.allKeys() {
        menu.addItem(NSMenuItem(title: "🚮 \(key)", action: Selector(deleteKey(key: "\(key)")), keyEquivalent: ""));
    }

    if let button = statusItem.button {
        button.title = "🔑"
        button.target = self }
        statusItem.menu = menu
        NSApp.activate(ignoringOtherApps: true)
  }

  func deleteKey(key: String) -> String {
    do {
        try addInternetPasswordVC().internetKeychain.remove("\(key)")
        print("key: \(key) has been removed")
    } catch let error {
        print("error: \(error)") }
    refreshMenu()
    return key
  }

...
}

我怀疑

  • 选项 1:选择器接受带有参数(或只是在某种程度上)的函数
  • 选项 2:我在第一行或最后一行的函数中犯了一个小错误。

最佳答案

目标/操作方法的签名要么不带参数,要么传递受影响的项目(在本例中为 NSMenuItem 实例),我怀疑它是否可以返回任何内容。

menu.addItem(NSMenuItem(title: "🚮 \(key)", action: #selector(deleteKey(_:)), keyEquivalent: ""));

...

func deleteKey(_ sender: NSMenuItem) {
    do {
        let key = sender.title.substring(from: sender.title.range(of: " ")!.upperBound)
        try addInternetPasswordVC().internetKeychain.remove("\(key)")
        print("key: \(key) has been removed")
        refreshMenu()
    } catch let error {
        print("error: \(error)") 
    }
}

PS:我猜调用 refreshMenu() 仅在按键被移除时才有用。

关于swift - Swift + NSMenuItem 中带有参数的 Selector(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40960560/

相关文章:

objective-c - 如何在没有编译器警告的情况下将 NSDecimalNumber 从 Objective-C 转换为 Swift 中的 Float

c++ - 在OS X上编译Boost时“ld: unknown option: -soname”

swift - 使用 "open"和 "public"

swift - 如何从 Swift 3 中的 UITableViewCell 引用当前的 UINavigationController?

multithreading - 在后台线程上的 NSBlockOperation 之后立即在主线程上运行一个 block

ios - UIBarButton 单击使用 Swift 4.2 设置标志值

ios - CLLocation 跟踪 iPhone 在哪条路上

swift - 绕过自动初始化器继承规则 Swift

ios - 在 Swift 3 中选择 UITableView 单元格后将字符串设置为 var

macos - 在 Cocoa App 中启用打开菜单