XCode: Swift - Display window as modal

In a previous blog was explained how you can create a window (NSWindow) that appears modal on a main window by sliding in from top. That article will explain the same issue with the difference of using programming language Swift instead of Objective C.
To get an impression what is ment, look at the image below.

Modal window

To display a NSWindow as modal you create a new subclass of NSWindowController . In the same step you can create the *.xib-file for Interface Builder like shown in the image below.

New file image

Before you start coding you should put a Close - Button to your new window. You will need that button to get rid of the window ;-)

Here is the code for subclassing NSWindowController:

import Cocoa

class MyModalWindowController: NSWindowController {

    var mainW: NSWindow = NSWindow()

    init() {
        super.init()
    }

    init(window: NSWindow!) {
        super.init(window: window)
        //Initialization code here.
    }

    init(coder: NSCoder!){
        super.init(coder: coder);
    }

    override func windowDidLoad() {
        super.windowDidLoad()
        // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
    }

    //method called to display the modal window
    func beginSheet(mainWindow: NSWindow){
        self.mainW = mainWindow
        NSApp.beginSheet(self.window, modalForWindow: mainWindow, modalDelegate: self, didEndSelector:nil, contextInfo: nil)

    }

    //method called, when "Close" - Button clicked
    @IBAction func btnClicked(sender: AnyObject) {
        self.endSheet();
    }

    //method called to slide out the modal window
    func endSheet(){
        NSApp.endSheet(self.window)
        self.window.orderOut(mainW)
    }
}

In your delegate-file of the mainwindow the subclass is allocated and initialized. To display the window you call beginSheet.

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet var window: NSWindow
    var mdlwin = MyModalWindowController(windowNibName: "MyModalWindowController")

    func applicationDidFinishLaunching(aNotification: NSNotification?) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification?) {
        // Insert code here to tear down your application
    }

    //method called, when button "Show Modal Window" is pressed
    @IBAction func buttonShowModalWindowPressed(sender: AnyObject) {
        mdlwin.beginSheet(self.window)
    }
}

So far so good! But it doesn't work like expected. The window doesn't slide in from top of the main window and is displayed somewhere on the screen but not in the top middle. And it cost me a lot of time to get the mistake. So pay attention, that you disable the property Visible At Launch in Attribute Inspector for the modal window.

Image Disable Visible At Launch

If you didn't create WindowController- and .xib-Files in one step or you have some trouble then check the setting in Interface Builder. At first select Files Owner object and check the identity inspector whether your WindowController-Class is referenced.

Image Class Reference for File Owner Object

Next step check the outlets- and delegate - connection. It has to look like the images below:

Image Outlet Delegate Connoctions with selected Files Owner

Image Outlet Delegate Connoctions with selected Window View

If you like you can download the Swift Code example as XCode project.

Werbung



comments powered by Disqus

Copyright Dunkel & Iwer GbR | Datenschutzerklärung | Impressum