I am a beginner Cocoa developer. The team I have been hired by does OS X development in Swift without using nib files (except apparently for the main menu). So, I am trying to learn this before I join the team. Here is what I have so far:
I created a new OS X project without storyboards. I created a new file called MainWindowController.swift, made it a subclass of NSWindowController and did not create a xib/nib file. I also made the MainWindowController implement the NSWindowDelegate protocol
In the MainMenu.xib file, I deleted the window that came with the app by default but I kept the main menu.
In the app delegate, I deleted the default outlet for the window.
I then created an NSWindow programmatically in the app delegate. I want the MainWindowController to be the delegate of this window. This is how my AppDelegate looks:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
let newWindow = NSWindow(contentRect: NSMakeRect(100, 100, NSScreen.mainScreen()!.frame.width/2, NSScreen.mainScreen()!.frame.height/2), styleMask: NSTitledWindowMask|NSResizableWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask, backing: NSBackingStoreType.Buffered, `defer`: false)
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
let wc = MainWindowController.init(window: newWindow)
wc.showWindow(self)
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
}
As you can see, I am creating a window object and then, in the applicationDidFinishLaunching method, I initialize my custom NSWindowController with that window and then show that window. I am not sure if any of this is correct.
Then, within my custom NSWindowController, I am making 'self' the delegate of the window using 'self.window?.delegate = self'. This is how my MainWindowController looks
import Cocoa
class MainWindowController: NSWindowController, NSWindowDelegate {
override func windowDidLoad() {
super.windowDidLoad()
self.window?.delegate = self
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
func windowDidMiniaturize(notification: NSNotification) {
print("Window minimized")
}
func windowWillClose(notification: NSNotification) {
print("Window closing")
}
}
As you can see, I have a couple of test prints in the delegate methods.
When I run the app, the window does show. However, when I minimize or close the window, nothing gets printed to the console. So, it appears that the delegate has not been set correctly for the window.
What is the correct way to do things?
In your AppDelegate
class, instead of storing your window in a property, you want to store your window controller. The way you have it now, there is no strong reference to the window controller, so it is destroyed when applicationDidFinishLaunching
finishes executing. The window controller will keep a strong reference to its window, so you should not need to keep a separate strong reference to the window. I would also set the window's delegate in applicationDidFinishLaunching
as well - I'm not sure if windowDidLoad
is called when you are not using a nib.
I think your AppDelegate
class should look something like this:
class AppDelegate: NSObject, NSApplicationDelegate {
let windowController = MainWindowController(
window: NSWindow(contentRect: NSMakeRect(100, 100, NSScreen.mainScreen()!.frame.width/2, NSScreen.mainScreen()!.frame.height/2),
styleMask: NSTitledWindowMask|NSResizableWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask,
backing: NSBackingStoreType.Buffered,
`defer`: false))
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
windowController.window?.delegate = windowController
windowController.showWindow(self)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With