swiftmacosinterface-buildernswindowcontrollernstoolbar

windowWillClose and button action not called Swift


I'm designing a mac app with Xcode 10 (beta) and I got an issue with the Preference Window Controller

I have in my Main.storyboard a NSWindowController of custom class PreferenceWindowController with a toolbar. Here are its connections : all NSWindowController connections

Here is the full class :

class PreferenceWindowController: NSWindowController, NSWindowDelegate {

@IBAction func didClickAuthor(_ sender: Any) {
    print("author")
}

@IBAction func didClickTypo(_ sender: Any) {
    print("typo")
}

override func windowDidLoad() {
    super.windowDidLoad()
}

func windowWillClose(_ notification: Notification) {
    print("willClose")
}
}

The window is initiated via the AppDelegate class with this code :

let storyboard = NSStoryboard(name: "Main",bundle: nil)

    if let wc = storyboard.instantiateController(withIdentifier: "PreferenceWindowController") as? PreferenceWindowController
    {
        wc.showWindow(self)
    }

The window opens as expected, with the toolbar clickable, but no functions from PreferenceWindowController are called at all, neither the closing of the window, nor the clicks on the toolbar.

I checked every connections, every class name, and I really don't know what's wrong...

SOLUTION

The solution is to store the PreferenceViewController class inside the AppDelegate class as a variable.

My solution :

var preferenceWindowController:PreferenceWindowController? = nil

@IBAction func clickPreferences(_ sender: Any) {
    if let wc = storyboard.instantiateController(withIdentifier: "PreferencesWindowController") as? PreferenceWindowController {
        let window = wc.window
        preferenceWindowController = wc

        wc.showWindow(self)
    }
}

Thank you for helping !


Solution

  • The comment above seems like it could be on the right track. Based on the code context you've included in your question, it looks like the window controller you create will only have a lifetime for that function call.

    Try making the window controller an instance variable. This is normally how I wire things up in an App delegate that creates window controllers. It's a simple pattern that works well.