即使应用程序退出,如何在菜单栏中显示应用程序图标 [英] How to display application icon in menubar even application is quit

查看:25
本文介绍了即使应用程序退出,如何在菜单栏中显示应用程序图标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序在菜单栏中显示一个图标,但当应用程序退出时,该图标从菜单栏中消失.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆