Programmatically create new window using a XIB file.

I have created a window using XIB that I want to open when pressing a menu option (Edit->OpenWindow). I can't figure out how to open a window and have it use the XIB I made. I have been searching for a solution for 3 whole hours. So my question is: how would I make a window open when I press a button? I am using Xcode 12.5, macOS 11.2.3, Swift.

In fact doc is not very helpful here.

So I will show a complete example in a MacApp.

The window is a status bar at the bottom of screen to show help messages.

  • 1.  Subclass a NSWindowController
class StatusWindowController: NSWindowController {

    @IBOutlet weak var helpMessageField: NSTextField!  // That is the unique item in the window ; you will have more
    
    //  set nib name for the window identical to file name
    override var windowNibName: NSNib.Name! { // StatusWindow.xib is the file nam for the xib
        return NSNib.Name("StatusWindow")
    }
    
    override init(window: NSWindow!) {
        super.init(window: window)
    }
    
    required init?(coder: (NSCoder?)) { // I had a warning here  Using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead - For NSCoder!
        super.init(coder: coder!)   // should check in case coder is nil ?
    }

    //    May not be needed, just in case 
    override func windowDidLoad() {
        super.windowDidLoad()
    }
}
  • 2.  create some global var (in fact, I created in a Singleton in the app) for the windowController instance
    var helpWindowController       : StatusWindowController?     
    var isHelpLineVisible = false
  • 3.  When needed, create the instance (take care not to create multiple times) ; I do it at the opening of the app to have it in place
        helpWindowController = StatusWindowController() 
  • 4.  Create Menu action showHelpAtBottom to be called by menu item:
    // ancillary func, as I need to use it elsewhere in code, to show / hide the window.
    func setHelpAtBottom() {
        
        if isHelpLineVisible {  // We have just made it visible by the menu action
            let origin = CGPoint.zero
            let size = CGSize(width: NSScreen.main!.visibleFrame.width, height: 13) 
             // it is a small window at bottom ; yours will be probably much larger
            let frame = NSRect(origin: origin, size: size)
            helpWindowController!.window!.setFrame(frame, display: true)
            helpWindowController!.window!.makeKeyAndOrderFront(Global.shared.helpWindowController!.window!)
         } else {
            // orderOut(_:) causes the window to be removed from the screen, but does not cause it to be released.
            helpWindowController!.window!.orderOut(nil)  
        }
    }
    
    @IBAction fileprivate func showHelpAtBottom(_ sender: NSMenuItem) {
        
        isHelpLineVisible = !isHelpLineVisible
        setHelpAtBottom()  
    }
  • 5.  Declare showHelpAtBottom as the menuAction for the menuItem (here a menu item in submenu) in IB by connecting the menuItem to the IBAction.

Hope that helps.

I forgot something:

  • 6.  The window in IB is declared of class StatusWindow

  • 7.  class is defined as:
class StatusWindow: NSWindow {

    func hideStatusWindow() {
        self.orderOut(nil)
    }

}
Programmatically create new window using a XIB file.
 
 
Q