I am trying to start a new document based Cocoa project in Swift and want to create a subclass of NSWindowController
(as recommended in Apple's guides on document based apps). In ObjC you would make an instance of an NSWindowController
subclass sending the initWithWindowNibName:
message, which was implemented accordingly, calling the superclasses method.
In Swift init(windowNibName)
is only available as an convenience initializer, the designated initializer of NSWindowController
is init(window)
which obviously wants me to pass in a window.
I cannot call super.init(windowNibName)
from my subclass, because it is not the designated initializer, so I obviously have to implement convenience init(windowNibName)
, which in turn needs to call self.init(window)
. But if all I have is my nib file, how do I access the nib file's window to send to that initializer?
Instead of overriding any of the init methods you can simply override the windowNibName
property and return a hardcoded string. This allows you to call the basic vanilla init method to create the window controller.
class WindowController: NSWindowController {
override var windowNibName: String! {
return "NameOfNib"
}
}
let windowController = WindowController()
I prefer this over calling let windowController = WindowController(windowNibName: "NameOfNib")
as the name of the nib is an implementation detail that should be fully encapsulated within the window controller class and never exposed outside (and it's just plain easier to call WindowController()
).
If you want to add additional parameters to the init method do the following:
super.init(window: nil)
. This will get NSWindowController
to init with the windowNibName
property.init(coder: NSCoder)
method to either configure your object or simply call fatalError()
to prohibit its use (albiet at runtime).class WindowController: NSWindowController {
var test: Bool
override var windowNibName: String! {
return "NameOfNib"
}
init(test: Bool) {
self.test = test
super.init(window: nil) // Call this to get NSWindowController to init with the windowNibName property
}
// Override this as required per the class spec
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented. Use init()")
// OR
self.test = false
super.init(coder: coder)
}
}
let windowController = WindowController(test: true)