After messing around with iOS apps, I thought I'd give a Cocoa app a whirl assuming things would be very similar. So I have a single window app with a split view and some NSTableView
s (think iTunes) and I'm looking for a place to put my code that will fetch data from the web to fill the tables.
In iOS I would put this in the viewDidLoad
method of the appropriate UIViewController
subclass. The UITableViewDataSource
would then access this data to populate its cells.
Now I have an NSWindow
for which I could do a similar thing but how do I make a NSWindowController
for it? Is this even what I want? I could put it in the AppDelegate
but doesn't seem right.
Best Solution
The difference between iOS and OS X is that there's only one window in iOS but there can be multiple in OS X.
NSViewControllers
in OS X work differently thanUIViewControllers
in that theNSViewController
is designed to load and handle a single view, whileUIViewControllers
(apologies for my relative lack of iOS knowledge) seem to handle multiple views and provide much more of the glue between views.Even the Apple docs write that:
Hence, the counterpart for
UIViewController
in OS X isn'tNSViewController
, but ratherNSWindowController
, which does provide for OS X much of whatUIViewController
does for iOS by managing the entirety of an individual window and the layout/content/interaction of the views within.In your case, I would use an
NSWindowController
- though if the app is very simple, theApp Delegate
works too; and if the app is very complex, then using aNSViewController
to split up the code wouldn't be a bad idea.The best way to do use an
NSWindowController
would be to programatically load it in the App Delegate using[[CustomWindowController alloc] init]
andOr calling
directly (and overriding initWithWindowNibName) if you want it to be reusable.
And you can delete the default window in MainMenu.xib.
Fundamentally, more often than not, an NSWindowController manages a window instantiated in its own nib file. The NSWindowController usually owns that nib file. (Though it is possible to have it manage a programmatically created window, that isn't usually how it's done.)
To be able to use a custom
NSWindowController
, you therefore need to make your window-to-be-managed in a separate nib/xib file. (using the default xib file means that you allow Cocoa to automatically instantiate a NSWindowController without opportunity for subclassing; you cannot use a customNSWindowController
with the default NSMainNibFile. For a simple app, just put all the controller code in the NSApplication/App Delegate)In Xcode 4 at least, the process involves creating a xib with the window template and the custom
NSWindowController
class, instantiating theCustomWindowController
class based on that nib in -init or wherever and then calling[CustomWindowController showWindow:self];
(or if that doesn't work,-makeKeyAndOrderFront:
) to get the window to actually show (in- (void)applicationDid/WillFinishLaunching:(NSNotification *)aNotification
might be a nice place).To stop the default window from showing I just delete it. There's probably a better way but I don't know that.