我的应用程序在菜单栏中显示一个图标但是当应用程序退出时,图标会从菜单栏中消失。
我们是否有办法对代码进行编码,即使退出,应用程序也会在菜单栏中进行重新设置。
感谢。
答案 0 :(得分:5)
你绝对可以将应用程序切换到后台(附件)模式,然后再返回。从语义上讲,应用程序永远不会退出。
基本思想是使用NSApplicationDelegate
协议在附件和常规应用模式之间来回切换。已有方法取消退出,捕获所有关闭的窗口,并处理尝试启动应用程序的用户,即使它仍在运行。所以把它们放在一起,你得到下面的代码。
我在这里留下代码,展示了如何加载和卸载由NSWindowController
self.wincon
控制的主GUI,其中self是应用程序委托对象。它加载并控制单独的MainWindow.xib
。如果您没有主菜单以外的窗口,则可能没有必要。
我还有一个用户首选项需要设置为启用所有这些行为。默认情况下,它真的会真的退出。
MainMenu.xib
中没有任何内容,但菜单 - 切换到附件模式意味着菜单不会显示。
// 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;
}
Notes添加了10/6/2016,因为这有一些牵引力:
有一个older answer to this question。它对变化的历史进行了很好的讨论,但缺乏示例代码。
最后,这个答案和问题完全缺少LSUIElement
关键字,这是此类应用程序的历史OSX plist设置。如上面的答案和this more recent question所述, LSUIElement
应被视为已弃用 。如果您发现了一篇提及它的旧博客文章,希望您找到了最近的代码示例,建议您不要使用它。