即使应用程序退出,如何在菜单栏中显示应用程序图标 [英] How to display application icon in menubar even application is quit
问题描述
我的应用程序在菜单栏中显示一个图标,但当应用程序退出时,该图标从菜单栏中消失.
My application shows a icon in the menu bar but when the application is quit the icon goes off from the menu bar.
我们有没有办法编写代码,使应用程序即使退出也总是停留在菜单栏中.
Do we have a way to code such that application always remian in the menu bar even it is quit.
谢谢.
推荐答案
您绝对可以将应用切换到后台(附件)模式,然后再返回.从语义上讲,应用程序永远不会退出.
You can definitely switch an app to background (Accessory) mode and back again. Semantically, the application never quits.
基本思想是使用 NSApplicationDelegate
协议在附件和常规应用程序模式之间来回切换.已经有一些方法可以取消退出,捕获所有关闭的窗口,并处理用户尝试启动您的应用程序,即使它仍在运行.所以把它们放在一起,你就会得到下面的代码.
The basic idea is to use the NSApplicationDelegate
protocol to switch back and forth between accessory and regular app modes. There are already methods to cancel quit, catch all windows being closed, and to handle the user trying to launch your app even if it's still running. So put it all together, and you get the code below.
我在这里留下了代码,展示了如何加载和卸载由 NSWindowController
self.wincon
控制的主 GUI,其中 self 是应用程序委托对象.它加载并控制一个单独的MainWindow.xib
.如果您没有主菜单以外的窗口,则可能没有必要.
I left in code here showing how to load and unload the main GUI controlled by the NSWindowController
self.wincon
where self is the application delegate object. It loads and controls a separate MainWindow.xib
. If you don't have a window other than the mainmenu, it might be unnecessary.
我还需要设置一个用户首选项以启用所有这些行为.默认情况下,它真的会退出.
I also have a user preference that needs to be set to enable all of this behavior. By default, it will really, really quit.
我在 MainMenu.xib
中没有任何内容,但是菜单 - 切换到辅助模式将意味着不显示菜单.
I have nothing in MainMenu.xib
but the menu-- switching to accessory mode will mean the menu is not displayed.
// Helper to close main window and switch to accessory mode
- (void) switchToBackgroundMode
{
@autoreleasepool {
// Need to check loaded to prevent closing a closed window and
// triggering a second call to applicationShouldTerminateAfterLastWindowClosed
if ([self.wincon isWindowLoaded]) [self.wincon close];
self.wincon = nil;
}
// Hide the menu and dock icon
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
}
#pragma mark Application Delegate Methods
// Called with a CMD-Q
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
// Cancel terminate if pref set
if ([MyPreferencesController runInBackground])
{
[self switchToBackgroundMode];
return NSTerminateCancel;
}
return NSTerminateNow;
}
// Called when all windows closed
- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
if ([MYPreferencesController runInBackground]) {
// This check is necessary to avoid calling switchToBGmode twice on a quit
if (![NSApp activationPolicy] == NSApplicationActivationPolicyAccessory)
[self switchToBackgroundMode];
return NO;
} else {
return YES;
}
}
// Called if the app is in accessory mode and the user activates it through the dock or by
// clicking a userNotification or trying to open the app
- (BOOL) applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
{
if (!self.wincon) {
self.wincon = [[MYMainWindowController alloc] initWithWindowNibName:@"MainWindow"];
}
// This ensures that the dock icon comes back
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
// Show the window
[self.wincon showWindow:NSApp];
[self.wincon.window makeKeyAndOrderFront:NSApp];
return YES;
}
注释于 2016 年 10 月 6 日添加,因为这引起了一些关注:
Notes added 10/6/2016 since this has gotten some traction:
有一个这个问题的旧答案.它对更改的历史进行了很好的讨论,但缺少示例代码.
There is an older answer to this question. It has a good discussion of the history of the changes but lacks sample code.
最后,这个答案和问题完全没有 LSUIElement
关键字,这是此类应用程序的历史 OSX plist 设置.如上面的答案和这个最近的问题,LSUIElement
应该被视为已弃用.如果您发现一篇提及它的旧博客文章,希望您找到了更多建议完全不要使用它的最新代码示例.
Finally, this answer and question entirely lacked the LSUIElement
keyword, which was a historical OSX plist setting for apps of this type. As described in the answer above and this more recent question, LSUIElement
should be considered deprecated. If you have found an old blog post mentioning it, hopefully you have found more recent code samples that recommend not using it at all.
这篇关于即使应用程序退出,如何在菜单栏中显示应用程序图标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!