Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OS X storyboard: how to show a window programmatically?

I am creating an OS X status bar application.

I am trying to achieve the following:

  • app starts invisible, with menu bar item
  • click on menu bar item shows the main window
  • on deactivate, the window is hidden

So I am trying to programmatically show the main window when the menu item is clicked, but with no success.

My main window has "Hide on deactivate" checked. Once hidden, I cannot make it visible again using code.

Here is the code I have for now, but it doesn't work:

@IBAction func menuClick(sender: AnyObject) {
    var mainWindow = NSStoryboard(name: "Main", bundle: nil)?.instantiateInitialController()
    mainWindow?.makeKeyAndOrderFront(self)
}
like image 621
Matthieu Napoli Avatar asked Nov 01 '22 11:11

Matthieu Napoli


2 Answers

This is how you have to do to show your Windows programmatically:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

     let mainWindow = NSWindow(contentRect: NSMakeRect(0, 0, NSScreen.mainScreen()!.frame.width/2, NSScreen.mainScreen()!.frame.height/2), styleMask: NSTitledWindowMask|NSResizableWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask, backing: NSBackingStoreType.Buffered, defer: false)

    func createNewWindow(){
        mainWindow.title = "Main Window"
        mainWindow.opaque = false
        mainWindow.center()
        mainWindow.hidesOnDeactivate = true
        mainWindow.movableByWindowBackground = true
        mainWindow.backgroundColor = NSColor(calibratedHue: 0, saturation: 0, brightness: 1, alpha: 1)
        mainWindow.makeKeyAndOrderFront(nil)
    }
    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // lets get rid of the main window just closing it as soon as the app launches
        NSApplication.sharedApplication().windows.first!.close()
    }
    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }
    @IBAction func menuClick(sender: AnyObject) {
        createNewWindow()
    }
}

or you can create an optional NSWindow var to store your window before you close it as follow

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    var defaultWindow:NSWindow?
    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // lets get rid of the main window just closing it as soon as the app launches
        defaultWindow = NSApplication.sharedApplication().windows.first as? NSWindow
        if let defaultWindow = defaultWindow {
            defaultWindow.close()
        }
    }
    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }
    @IBAction func menuClick(sender: AnyObject) {
        if let defaultWindow = defaultWindow {
            defaultWindow.makeKeyAndOrderFront(nil)
        }
    }
}
like image 142
Leo Dabus Avatar answered Nov 15 '22 07:11

Leo Dabus


The makeKeyAndOrderFront method is a NSWindow method, but instantiateInitialController returns the window controller, not its window.

Also, if the window is hidden on deactivate, you wouldn't want to instantiate another copy. Keep a reference to the window and re-show that.

Finally, you may need to bring the app to the front too. Call [NSApp activateIgnoringOtherApps:YES] (or the Swift equivalent).

like image 38
Dejal Avatar answered Nov 15 '22 05:11

Dejal