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

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

问题描述

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



我们有办法



感谢。

解决方案

div>

您可以将应用程序切换到后台(附件)模式,然后再返回。语义上,应用程序从不退出。



基本思想是使用 NSApplicationDelegate 协议来回切换附件和常规应用程序模式。已经有方法来取消退出,捕获所有窗口关闭,并处理用户尝试启动您的应用程序,即使它仍然运行。所以把它放在一起,你得到下面的代码。



我离开代码在这里展示如何加载和卸载由 NSWindowController self.wincon 其中self是应用程序委托对象。它加载并控制单独的 MainWindow.xib 。如果您没有主菜单以外的窗口,则可能不必要。



我还有一个用户首选项,需要设置为启用所有此行为。



我在 MainMenu.xib 中没有任何东西,但菜单 -

  //帮助关闭主窗口并切换到附件模式
- (void)switchToBackgroundMode
{
@autoreleasepool {
//需要检查加载以防止关闭关闭的窗口和
//触发第二次调用applicationShouldTerminateAfterLastWindowClosed
if([self.wincon isWindowLoaded])[self.wincon close];
self.wincon = nil;
}

//隐藏菜单和dock图标
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
}

#pragma mark应用程序委托方法

//使用CMD-Q调用
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
//取消终止if pref设置
if([MyPreferencesController runInBackground])
{
[self switchToBackgroundMode];
return NSTerminateCancel;
}
return NSTerminateNow;
}

//所有窗口关闭时调用
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
if([MYPreferencesController runInBackground] ){
//这个检查是必要的,以避免在退出时调用switchToBGmode两次
if(![NSApp activationPolicy] == NSApplicationActivationPolicyAccessory)
[self switchToBackgroundMode];
return NO;
} else {
return YES;
}
}

//如果应用程序处于附件模式,并且用户通过Dock或通过
//单击userNotification或尝试打开应用程序
- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
{
if(!self.wincon){
self.wincon = [MYMainWindowController alloc] initWithWindowNibName:@MainWindow];
}

//这确保dock图标返回
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

//显示窗口
[self.wincon showWindow:NSApp];
[self.wincon.window makeKeyAndOrderFront:NSApp];
return YES;
}

p>

有一个这个问题的旧答案



最后,这个答案和问题完全缺少了 LSUIElement 关键字,这是一个历史OSX plist设置这种类型的应用程序。如上述答案和这个更新的问题 LSUIElement 应被视为已弃用 。如果你发现一个旧的博客文章提到它,希望你发现更多的最近的代码示例,建议不要使用它。


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.

Thanks.

解决方案

You can definitely switch an app to background (Accessory) mode and back again. Semantically, the application never quits.

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.

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.

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;
}

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.

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天全站免登陆