linking file menu items to buttons - objective-c

I'm in need of linking some buttons in a 'document based' application to the file menu (bold text, italic text, make text bigger etc.). The issue is that since its a document based application, the MainMenu.xib is a completely different XIB file than the MyDocument.xib, so I can't drag the connections in Interface Builder like I usually would. Does anyone have a workaround? Is there a way to link button actions to a separate XIB files' built in menu functions?
Zach

Generally, you use the First Responder place-holder object.
About the First Responder
"In Interface Builder, the First Responder is a proxy object that represents the first object in your application’s dynamically determined responder chain. Because the responder chain of an application cannot be determined at design time, the First Responder proxy acts as a stand-in target for any action messages that need to be directed at the application’s responder chain. Menu items commonly target the First Responder proxy. For example, the Minimize menu item in the Window menu hides the frontmost window in an application, not just a specific window, and the Copy menu item should copy the current selection, not just the selection of a single control or view. Other objects in your application can target the First Responder as well."
Also see:
Connecting Menu Items Across Nib Files
Also, if you want to create buttons whose actions are basically the same as the Format > Bold, etc. commands, see: Connecting the Font Menu in Interface Builder 3

Related

Mac application About menu customisation

I am doing my first mac application. I have added my menus and customized. What is my problem is that I need some customizations in the about view. While the about menu clicked, automatically a view will pops up with details Name, Icon, copyright string, version etc. fetched from application plist. About menu in XCode application, which has buttons for Acknowledgment and Licensee Agreement. In chrome About Chrome will create a new tab in the webpage and details are shown. How this possible? Any help is appreciated.
It seems that you can do it in your MainMenu.xib, change to the target-action of the menu item About myApp to your custom action.
See the doc:
Connecting Menu Items Across Nib Files
The items in an OS X application’s menu bar often need to interact
with many different objects, including your application’s documents
and windows. The problem is that many of these objects cannot (or
should not) be accessed directly from the main nib file. The File’s
Owner of the main nib file is always set to an instance of the
NSApplication class. And although you might be able to instantiate a
number of custom objects in your main nib file, doing so is hardly
practical or necessary. In the case of document objects, connecting
directly to a specific document object is not even possible because
the number of document objects can change dynamically and can even be
zero.
Most menu items send action messages to one of the following:
A fixed object that always handles the command
A dynamic object, such as a document or window
Messaging fixed objects is a relatively straightforward process that
is usually best handled through the application delegate. The
application delegate object assists the NSApplication object in
running the application and is one of the few objects that rightfully
belongs in the main nib file. If the menu item refers to an
application-level command, you can implement that command directly in
the application delegate or just have the delegate forward the message
to the appropriate object elsewhere in your application.
If you have a menu item that acts on the contents of the frontmost
window, you need to link the menu item to the First Responder
placeholder object. If the action method associated with the menu item
is specific to one of your objects (and not defined by Cocoa), you
must add that action to the First Responder before creating the
connection.
After creating the connection, you need to implement the action method
in your custom class. That object should also implement the
validateMenuItem: method to enable the menu item at appropriate times.
For more information about how the responder chain handles commands,
see Cocoa Event Handling Guide.

OSX Cocoa using tab to navigate between child controls within a view not working

I am new to Xcode/OSX UI so there is probably something silly I'm overlooking. This is XCode 5.11 targeting OSX 10.10 desktop.
I have inherited some code with a few views where navigating among child controls within the view using the tab key does not work.
In researching this almost everything says to be sure to set the first responder and then chain your controls using nextKeyView.
I followed the steps in this video https://www.youtube.com/watch?v=SRrE8eqp0dU (XCode 4, but all the functionality seemed to be the same for 5.11) to no avail.
I also had a look at this solution How to make child controls of view will get focus on Tab and Shift+Tab in NSViewController which sounds like a similar issue to what I am seeing, but one of the classes I inherited uses NSWindowController vs. NSViewController as the base and there is no loadView to override and the other which did derive from NSViewController did not behave any differently with the changes made to loadView.
When my window launches my first responder control (NSTextField in this case) has focus (blue highlight) but tab key is ignored and focus will not change unless I use the mouse.
So it's really not a tab ordering issue initially, it seems like a tab ignored issue and who knows what the ordering is. I tried setting focus to a NSButtonCell and NSPopUpButton using the mouse and then tab navigate from those to see if there was some issue with my NSTextField but they exhibit the same behavior. None of the controls are set to "Refuses First Responder" which was another setting it was recommended to check.
I'm at a loss and looking for any other things to try or check.
The first view I am having an issue with is: Window / Child View / Multiple Child Boxes / Multiple controls per box in case that matters or complicates things. It is basically for setting application Preferences.
The second view seems like it may be more complicated in that there is a single Window that swaps out its child view in a next/back progression (wizard interface). The initial window nib is "blank" so I didn't see how to associate a first responder from IB like I did with the Preferences window since all the controls are on their own individual view nibs (these all show as "Custom View" vs. just "View" for Preferences).
The resolution for me was to ensure that the "Auto Recalculates View Loop" setting in the Attributes Inspector was enabled for the windows hosting these views. This corresponds to the autorecalculatesKeyViewLoop property of NSWindow.

Main Menu in different nibs

I have a Cocoa app with a ManMenu.xib, in which the main menu is stored and different other subviews in several xibs handling different tasks of my app. So how do I make my sub-xibs or rather their NSViewControllerController receive actions from the menu?
i have an idea but I don't know if it's the right way: I subclass NSViewController and add some actions like - (IBAction)undo or - (IBAction)redo use instances of it as the files owner. Further I add a pointer to my app delegate pointing at the actual view or rather its controller and the menu sends the action to that pointer.
Wise solution?
You should hook up your menu items to the First Responder. Their action messages will then travel along the responder chain until they reach something that responds to them.
You'll need to make sure your view controller is in the responder chain by setting it as the next responder of something else in the responder chain. I would suggest the window controller.
Speaking of the window controller, you probably should be handling undo there rather than in a view controller—it would be confusing for different views in the same window to have different undo lists. The only exception I can think of would be if the controlled views correspond to document tabs, like in Photoshop or Xcode.

Bold + Italic Shortcuts in Document-Based Applications

I've been reading into using the First Responder as a proxy object, and dragging connections from buttons in order to create usable actions (align left, right, etc). However, by default, the First Responder doesn't contain Bold and Italic actions. I tried adding these actions by opening my Menu.xib and dragging the (Font > Bold) menu item to the first responder and setting it as a boldIt function (custom) but that overwrites the existing action (Font Manager: Addtrait). Is there a way to somewhat efficiently add a bold/italic button on the document.xib? Seems like a lot of work for something so common. New to Obj-C
Best,
Zach
In the menu xib, there is an object (the Bold menu item), whose tag is 2, and whose action is connected to the -addFontTrait: method of an NSFontManager instance.
You simply need to do the same thing in document xib. Add an NSFontManager object; create your Bold button; set its tag to 2; and connect its action to -addFontTrait on the NSFontManager.

Enabling open file menu item in a non-document-based application

I would like to enable the grayed out open file menu item within a non-document-based application. Document-based applications automatically give you a nice open file dialog with file extension filters based on plist entries etc... Surely, a simple elegant method exist to re-enable this functionality.
I have...
Added document types to the project properties window
Assigned my controller class as the application delegate
Added the delegate application:openFile: to my controller class
First, make sure your File->Open menu item's selector is connected to the openDocument: action of the First Responder.
Second, make sure you are responding to the action. Take a look at the Responder chain of a non-document application with an NSWindowController object. Any object within your responder chain can respond to the message, but it is best to pick the object which is the most capable and appropriate. Once you have decided which class in your responder chain is the most appropriate to handle the message, add the openDocument: action to it's implementation and write your code to respond to it accordingly.
The key is that something along the menu item's responder chain has to respond to the -openDocument: action. Normally it's the NSDocumentController. I'd take a look at how an empty document-based application sets up that menu item.