Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
287 views
in Technique[技术] by (71.8m points)

objective c - 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.

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...