【发布时间】:2020-01-07 20:58:04
【问题描述】:
我有以下代码:(可以复制粘贴到新的 macOS 项目)
import Cocoa
import SwiftUI
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var statusBarItem: NSStatusItem!
func applicationDidFinishLaunching(_ aNotification: Notification) {
let statusBar = NSStatusBar.system
statusBarItem = statusBar.statusItem(
withLength: NSStatusItem.squareLength)
statusBarItem.button?.title = "????"
// Setting action
statusBarItem.button?.action = #selector(self.statusBarButtonClicked(sender:))
statusBarItem.button?.sendAction(on: [.leftMouseUp])
let statusBarMenu = NSMenu(title: "Status Bar Menu")
statusBarMenu.addItem(
withTitle: "Order an apple",
action: #selector(AppDelegate.orderAnApple),
keyEquivalent: "")
statusBarMenu.addItem(
withTitle: "Cancel apple order",
action: #selector(AppDelegate.cancelAppleOrder),
keyEquivalent: "")
// Setting menu
statusBarItem.menu = statusBarMenu
}
@objc func statusBarButtonClicked(sender: NSStatusBarButton) {
let event = NSApp.currentEvent!
if event.type == NSEvent.EventType.rightMouseUp {
print("Right click!")
} else {
print("Left click!")
}
}
@objc func orderAnApple() {
print("Ordering a apple!")
}
@objc func cancelAppleOrder() {
print("Canceling your order :(")
}
}
实际行为:菜单在左右单击时打开,未触发 statusBarButtonClicked。
删除此行后:
statusBarItem.menu = statusBarMenu
statusBarButtonClicked 在左键单击时触发,菜单未显示(如预期)
所需行为:右键单击菜单打开,左键单击菜单未打开,动作被触发。
如何实现?
编辑
在@red_menace 评论的帮助下,我设法实现了预期的行为:
import Cocoa
import SwiftUI
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var statusBarItem: NSStatusItem!
var menu: NSMenu!
func applicationDidFinishLaunching(_ aNotification: Notification) {
let statusBar = NSStatusBar.system
statusBarItem = statusBar.statusItem(
withLength: NSStatusItem.squareLength)
statusBarItem.button?.title = "????"
// Setting action
statusBarItem.button?.action = #selector(self.statusBarButtonClicked(sender:))
statusBarItem.button?.sendAction(on: [.leftMouseUp, .rightMouseUp])
let statusBarMenu = NSMenu(title: "Status Bar Menu")
statusBarMenu.addItem(
withTitle: "Order an apple",
action: #selector(AppDelegate.orderAnApple),
keyEquivalent: "")
statusBarMenu.addItem(
withTitle: "Cancel apple order",
action: #selector(AppDelegate.cancelAppleOrder),
keyEquivalent: "")
// Setting menu
menu = statusBarMenu
}
@objc func statusBarButtonClicked(sender: NSStatusBarButton) {
let event = NSApp.currentEvent!
if event.type == NSEvent.EventType.rightMouseUp {
statusBarItem.popUpMenu(menu)
} else {
print("Left click!")
}
}
@objc func orderAnApple() {
print("Ordering a apple!")
}
@objc func cancelAppleOrder() {
print("Canceling your order :(")
}
}
但是 Xcode 说 openMenu func 在 10.14 中已弃用,并告诉我 Use the menu property instead。有没有办法通过新的 API 实现所需的行为?
【问题讨论】:
-
将
NSRightMouseUpMask添加到sendActionOn:,不要将菜单设置为statusBarItem。然后只需检查 action 方法中的事件,如果事件为NSEventTypeRightMouseUp,则使用popUpStatusItemMenu:显示菜单。请注意,其中一些方法在 Catalina 中已被弃用。 -
@red_menace 感谢您的回答 :)。你是说
popUpMenu:?我找不到popUpStatusItemMenu。如果是这样,popUpMenu 有效,但在 10.14 中已弃用。警告显示“改用菜单属性” -
对不起,
popUpStatusItemMenu是 Obj-C,Swift 是popUpMenu。在 Catalina 中,popUpMenu和sendAction是不推荐使用的 NSStatusMenu 方法。在 NSButton 上有一个sendAction方法,但等效于popUpMenu将类似于设置状态项菜单并在操作方法中显示它(例如通过 NSControl 的performClick),然后在完成后删除菜单,以便它不用于状态项的正常行为。我不太了解 Swift,无法提供一个像样的例子。
标签: swift macos cocoa swiftui appkit