Opening a window for status bar OS X 10.10 applica

2019-08-15 14:50发布

问题:

I'm developing a status bar OS X application with Swift 1.2 and storyboards.

My application doesn't have an initial controller because I don't want any windows to be displayed when the app is being launched. But, I need to open a preferences window if the app hasn't been configured. How do I do that properly? Now I'm doing that with NSPopover, but that's an ugly solution and doesn't provide a good UX.

Is there a way to open a window, a view controller, if an application doesn't have an entry point, an initial controller? I have a feeling that my architecture might be wrong. Thanks.

import Cocoa

let kPreferences = "preferences"

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var statusMenu: NSMenu!

    let popover = NSPopover()
    var statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-2)

    func applicationDidFinishLaunching(aNotification: NSNotification) {

        syncronizeExcercises()

        // Status menu icon
        let button = statusItem.button
        button!.image = NSImage(named: "statusIcon")

        statusItem.menu = statusMenu

        let defaults = NSUserDefaults.standardUserDefaults()
        if let prefences = defaults.stringForKey(kPreferences) {
            println(prefences)
        } else {
            let preferencesViewController = NSStoryboard(name: "Main", bundle: nil)?.instantiateControllerWithIdentifier("PreferencesViewController") as! PreferencesViewController
            preferencesViewController.notConfigured = true

            popover.contentViewController = preferencesViewController
            popover.showRelativeToRect(button!.bounds, ofView: button!, preferredEdge: NSMinYEdge)
        }
    }

回答1:

Okay, I ended up creating an initial view controller and now showing the main window in case the app is configured.

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var statusMenu: NSMenu!

    var window: NSWindow?
    let popover = NSPopover()
    var statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-2)

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        window = NSApplication.sharedApplication().windows.last! as? NSWindow
        window!.close()

        syncronizeExcercises()

        // Status menu icon
        let button = statusItem.button
        button!.image = NSImage(named: "statusIcon")

        statusItem.menu = statusMenu

        let defaults = NSUserDefaults.standardUserDefaults()
        if let prefences = defaults.stringForKey(kPreferences) {
            println(prefences)
        } else {
            let preferencesViewController = window?.contentViewController as! PreferencesViewController
            preferencesViewController.notConfigured = true

            window?.makeKeyAndOrderFront(nil)
        }
    }


回答2:

You can always manually load an instance of NSStoryboard (some init method with the file name). Then you can get the initial view controller from that storyboard and present it. You just have to set the initial view controller in your sotryboard editor and it should work like this.

Although there is a problem with this I have faced for a long time but still got no solution: i too wanted to create such an application, I used my method, but when you think you want to close the window with CMD-Q it actually quits the application (obviously)