Where to put MainMenu.xib selector? - cocoa

I have a new project I am working on in Xcode 5.1 and I have been using Interface Builder to create and bind most of my layouts. I customized the default MainMenu.xib to contain the menu items I want but I cannot figure out how to bind the selectors for each menu item.
The project has a MainWindow.xib and a MainWindowController that is used by my app delegate and the controller is where I would expect the menu selectors to go, but I don't know how to do that.
The drag-and-drop connections panel will not work with the controller.
The MainMenu.xib's owner is the NSApplication, which doesn't seem right for the selector.
How do (and where should) I handle the MainMenu.xib actions?
Note: my question is very similar to this one but since I have done everything in IB and the accepted answer is in obj-c, the answer is of no use to me.

In my own project, I have a MainMenu.xib and a MainWindow.xib file.
MainMenu.xib is the default starting xib file when one isn't using a storyboard for an app. That's why NSApplication lives in there, it needs to be instantiated.
My MainWindow.xib is owned by my own MainWindowController implementation.
For the various menu items in MainMenu.xib, I am pointing those items at my AppDelegate (which is the true file owner for MainMenu.xib), and with those IBActions I'm firing off methods in other objects, notifications to other objects, or instantiating objects to get whatever task done that's associated with that menu item.
If you have additional classes & objects instantiated within MainMenu.xib, you can add IBActions in those classes and connect the menu items directly to them.

Related

What is the purpose of the Application placeholder in a MainMenu.xib file in Interface Builder?

Apple’s developer documentation on Nib Files in Interface Builder mentions the Application placeholder (highlighted in the picture above) but doesn’t explain its purpose or when it should be used. The article explains the other two placeholders—File’s Owner and First Responder—fairly well.
I would appreciate any information on the Application placeholder, with links to any documentation that I may have missed.
Also, in the Identity Inspector, why is the Application placeholder of type NSObject instead of, for example, NSApplication?
From the documentation of Interface Builder 3.2.6 (copyright 1999-2010):
In Cocoa nib files, the Application placeholder object gives you a way to connect the outlets of your application's shared NSApplication object to custom objects in your nib file. The default application object has outlets for its delegate object and, in Cocoa applications, the application menu bar. If you define a custom subclass of NSApplication, you can connect any additional outlets and actions defined in your subclass.
In an old MainMenu.nib file from 2009, the delegate is connected to the Application placeholder instead of the file's owner. In a XIB file from 2012, the Application placeholder isn't class NSObject. Nowadays the only use I can think of is binding something to Application.delegate.someProperty.

Accessing menu items from view controller in a storyboard, OS X, swift

I am building an OS X app in Xcode using storyboards. I have found that working with menu items is difficult and non-intuitive. The menu items are in a different scene (the application) than the view controller, and can not be connected to the view controller by the usual control-drag methods to create an outlet/action. I need to access menu items from the main view controller. I have figured out how to connect actions via first responder chain. However, I also would like to enable/disable menu items from the view controller, and I see no way to create an outlet to be able to do this.
I am new to OS X programming. I feel like I am missing something very basic here. I have watched several WWDC videos related to storyboards, and have not seen a good example showing the proper way to work with menus. Any help would be most appreciated.
There are several ways to work with menus. The traditional Cocoa way is to add an action method to First Responder proxy in IB.
Then flesh out the same action method in the NSResponder subclass that you want. Declare it in the header too.
This will then receive the action message via the Responder Chain.
Read up on the Responder Chain.

asp.net vs. xcode button click

I just started learning objective c and iphone development. Coming from an asp.net and web development, I am so lost with xcode.
In asp.net, you create a button, then you can simply click on it and it takes you right to the button event. Vs. Xcode, you create a button, then you will have to create an outlet in the header file, property, IBaction. Then in the implementation (.m) file, you create the click event method for that button. After that, you have to create an outlet reference of that button touch to that event by draging...
Just out of curiosity, is there any shortcuts or easier way to do this like asp.net? Without having to create outlet, property, etc. If there are any ways to eliminate some steps would be helpful.
If you want to perform action only click button you don't need to declare UIButton IBOutlet.
Just simply drag UIButton object on your view then declare & implement IBAction method in your class. Then make connection between action and button.
There is not shortcut in xcode for this if you want to interact with interface objects in your controller class you need to declare them as property and implement using #synthesize

High-Level App Design/Architecture

I've done a fair amount of iOS development in the past couple of years, so I'm pretty familiar with iOS architecture and app design (everything's a ViewController that you either push, pop, or stick into tab bars). I've recently started exploring proper Mac app development and feel a little lost. I'd like to really just have a sanity check and maybe some advice as to what the proper way to build an app like this is:
I'd like to build a library-style, single window app, that will spawn additional windows during its operation, but not as full-blown documents. The main window will be laid out much like OS X Lion's Mail.app, with a three-wide split view containing:
A source list, or high-level topic selection
A list view of items pertaining to the topic selected in the first pane
A detail view, which shows the details of the object selected in the middle pane
Like I said, really similar to Mail.app as far as looks go.
My question is really how to glue all this together from inside XCode. Here's where my confusion lies so far:
The default project generated a NIB with a main menu and window. I like to encapsulate functionality, so should I make a window controller for this window and somehow hook it up in Interface Builder, or does window-specific functionality belong somewhere else?
If possible, I'd like each of my three panes to be separate view controllers. I created three NSViewController subclasses (XCode automatically generated NIBs), and added (to the main menu/window NIB) view controller objects with each class specified, hooking up each one's view property to one of the three Custom View generic NSView objects I dropped into the NSSplitView. When I tried to set each view controller's NIB, only the main menu/window NIB appeared in the drop-down, and typing the desired one by hand seemed to have no effect (the view's contents didn't actually appear when running the app). This makes me think I'm doing something wrong.
I'm a little fuzzy on what types of views I should use for each of the first two panes. I'll obviously build a custom one for the final pane, but it seems like the first two should be present in the Cocoa framework already.
Anyway, if I'm doing completely the wrong thing, don't bother addressing my questions; just tell me what I should be doing instead. I think I just need a proper Mac developer to point me in the right direction.
With regard to your first question, you don't need to use the main window that Apple supplies in MainMenu.xib. If you want, you are free to delete that window from the nib and then instantiate an NSWindowController in your applicationDidFinishLaunching: delegate method which then loads and controls the main window.
You are definitely confused about NSViewController, which is not really all that surprising, since you might assume that it works like UIViewController.
In fact, NSViewController is completely different to UIViewController and does not have the same level of Interface Builder support. You can't place a view controller in a window in IB, for example, whereas this is standard practice on iOS. NSViewController is a relatively new class on the Mac and generally you use it to load views programmatically and manage the view content.
The class that most closely maps to UIViewController on the Mac is NSWindowController. This has been around a lot longer than NSViewController and in fact many Mac apps don't use NSViewController at all.
Generally, each window in your app should have a window controller managing it. You can use subclasses of NSWindowController to handle a lot of the functionality for each window.
If you want to use NSViewController, then you should use your window controller to manage those view controller objects. This is generally done programmatically due to the aforesaid lack of Interface Builder support. Each NSViewController instance loads its view from a specific nib file. You generally don't add view controllers in Interface Builder.
For your source list you would generally use an NSOutlineView if you have multiple sections or an NSTableView. These two objects are used whenever you need a list of items. NSOutlineView is hierarchical, whereas NSTableView is flat.
I hope this helps.

Create instance of class in nib file

Im going through Apple's OSX Cocoa (Your First Mac Application) tutorial and am up to refactoring the app delegate. I have created my own controller class.
I don't understand how to "Create an instance of the controller class in the nib file". I'm using Xcode 4.
Drag an 'Object' from the 'Object Library' in the right pane onto your nib. Next, select the object that you dragged into the nib, and then select the identity inspector (third icon from the left in the top right pane). From these, you can set a custom class. Set the class to be the custom controller that you have created. This will be created for you when the nib is initialized. You can then connect this to an IBOutlet in your AppDelegate (for that custom class).
I think what you want is on the inspector, click the third tab, and for the "Custom Class", select your view controller.

Resources