Swift macOS菜单栏应用程序:未显示主菜单
我有一个状态栏应用程序,它在菜单栏中运行。因此,我在Swift macOS菜单栏应用程序:未显示主菜单,swift,macos,cocoa,background-process,menubar,Swift,Macos,Cocoa,Background Process,Menubar,我有一个状态栏应用程序,它在菜单栏中运行。因此,我在info.plst中将Application is agent(UIElement)设置为true。这导致我的应用程序没有停靠图标和菜单栏 但是,我还有一个用户可以从statusbar菜单打开的首选项窗口。下面是我打开它的方式: if (!NSApp.setActivationPolicy(.regular)) { print("unable to set regular activation policy") } NSApp.acti
info.plst
中将Application is agent(UIElement)
设置为true
。这导致我的应用程序没有停靠图标和菜单栏
但是,我还有一个用户可以从statusbar菜单打开的首选项窗口。下面是我打开它的方式:
if (!NSApp.setActivationPolicy(.regular)) {
print("unable to set regular activation policy")
}
NSApp.activate(ignoringOtherApps: true)
if let window = preferencesWindowController.window {
window.makeKeyAndOrderFront(nil)
}
窗口按预期显示,但应用程序的主菜单栏(包含文件、编辑等)不显示。只有当我单击另一个应用程序并返回到我的应用程序时,才会显示菜单栏 我注意到,如果我将
info.plst
中的值更改为false
,并在applicationdFinishLaunching()
中使用NSApp.setActivationPolicy(.association)
,则结果相同。但是,如果在调用applicationdFinishLaunching()
几毫秒后,我使用计时器调用NSApp.setActivationPolicy(.accessority)
,它将正常工作,主菜单将按预期显示。然而,这样做的副作用是,应用程序图标会在dock中弹出几秒钟(直到计时器被触发),这不是一个好的用户体验
有人知道我还能尝试什么吗?当我切换活动应用程序时,代码中没有执行的操作会发生什么
我正在macOS 10.12.2(16C67)上使用版本8.2.1(8C1002)
谢谢 这是我目前的解决方案: 正如我在问题中所写的,如果我点击另一个应用程序并返回到我的应用程序,菜单栏就会显示出来。当我尝试显示首选项窗口时,我正在模拟此操作:
NSApp.setActivationPolicy(.regular)
NSApp.activate(ignoringOtherApps: true)
window.makeKeyAndOrderFront(nil)
if (NSRunningApplication.runningApplications(withBundleIdentifier: "com.apple.dock").first?.activate(options: []))! {
let deadlineTime = DispatchTime.now() + .milliseconds(200)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
NSApp.setActivationPolicy(.regular)
NSApp.activate(ignoringOtherApps: true)
}
}
这不是一个完美的解决方案。如果我找不到更好的解决方案,我将提交一个bug。我尝试了apple脚本,它看起来像预期的那样工作 除此之外,在通过按键关闭然后重新打开新窗口(短时间间隔)后,菜单将保持选中状态 GIF演示: 基于OP的修复(或解决方法)。关键是切换到焦点(谢谢@Daniel!) 一些小的改进: 无需强制展开,无需设置ActivationPolicy并调用activate两次
NSApp.setActivationPolicy(.regular)
window.makeKeyAndOrderFront(nil)
NSRunningApplication.runningApplications(withBundleIdentifier: "com.apple.dock").first?.activate(options: [])
OperationQueue.current?.underlyingQueue?.asyncAfter(deadline: .now() + .milliseconds(200), execute: {
NSApp.activate(ignoringOtherApps: true)
})
我可能会为此找到另一个解决方案(这在macOS 10.15上仍然是一个问题)。我发现了一个类似的问题+解决方案。idea将显示和隐藏当前应用程序的菜单栏。我需要运行它两个不同的运行循环,但它工作。以下是解决方案:
OperationQueue.main.addOperation{
NSMenu.setmenubavisible(false)
OperationQueue.main.addOperation{
NSMenu.setmenubavisible(true)
}
}
我找到了另一种解决方案,它不需要对dock和back进行调焦,在应用程序退出/进入focus时会引起闪烁。
这将在下一个勾选中将激活策略设置为禁止,然后设置为常规:
如果NSApp.activationPolicy()!=。正规的{
NSApp.setActivationPolicy(.违禁)
DispatchQueue.main.asyncAfter(截止日期:DispatchTime.now()+毫秒(200)){
NSApp.setActivationPolicy(.regular)
NSApp.activate(忽略其他应用程序:true)
车窗。MakeKeyandDerfront(无)
}
}否则{
//激活策略已经正常,只需正常打开窗口即可
NSApp.activate(忽略其他应用程序:true)
车窗。MakeKeyandDerfront(无)
}
“窗口按预期显示”我假设该窗口也会成为第一响应者,看起来不像是背景或其他东西。对吗?我的应用程序也遇到了这个问题。你并不孤单:)我也有同样的问题,我还没有找到有效的解决方案。您在哪里运行上述代码?在AppDelegate的ApplicationIDFinishLaunching函数中?您好!你有没有找到更好的解决办法?没有。对不起,谢谢你的回答。注意:苹果的脚本在Mac应用商店上不起作用。我认为如果你的应用程序是沙盒的话,它根本不起作用。谢谢你的建议。不幸的是,菜单栏出现了,但单击菜单栏上的项目不起作用。我用它修复了一个问题,该问题锁定了与菜单栏的交互,当我使用应用程序的图标(保持在dock中)重新打开以前隐藏的应用程序窗口以进入statusbar应用程序状态时会发生这种情况
NSApp.setActivationPolicy(.regular)
window.makeKeyAndOrderFront(nil)
NSRunningApplication.runningApplications(withBundleIdentifier: "com.apple.dock").first?.activate(options: [])
OperationQueue.current?.underlyingQueue?.asyncAfter(deadline: .now() + .milliseconds(200), execute: {
NSApp.activate(ignoringOtherApps: true)
})