Cocoa Programming for Mac OS X - Aaron Hillegass [34]
Figure 5.10. Enable the Assistant Editor
In Chapter 2 we learned how to create outlets and actions and how to create connections between user interface objects by using Interface Builder. We could type out all the outlets and actions for this project as before. Instead, we will use the Assistant Editor to make our task much easier.
Making Connections in Interface Builder
Making a connection is analogous to introducing people. You say, “Mrs. Robinson, this is Dr. Pepper.” If it is important that Dr. Pepper also know Mrs. Robinson, you would continue, “Dr. Pepper, this is Mrs. Robinson.” With objects in Interface Builder, you will drag from the object that needs to know to the object that it needs to know about. You might also drag the other way to create a connection in the opposite direction, if necessary.
For example, when a user clicks the Stop button, the button needs to send a message to your SpeakLineAppDelegate, so the button needs to know about the SpeakLineAppDelegate. For this reason, you will Control-drag from the button to the SpeakLineAppDelegate. However, instead of dragging to the blue object in the Interface Builder dock as we did before, we will Control-drag from the button to the interface definition area within the Assistant Editor, as shown in Figure 5.11. In the pop-over that appears, set the Connection to Action, enter stopIt: for the Name, and click Connect. An IBAction line will appear at the insertion point.
Figure 5.11. Set Action for Stop Button
Now Control-drag from the Speak button to the SpeakLineAppDelegate.h interface again in order to create an action named sayIt:.
In order to synthesize the speech for the line of text, the SpeakLineAppDelegate will need to ask the text field for the line of text. Thus, the SpeakLineAppDelegate needs to have a pointer to the text field. This time, Control-drag from the text field to just below the window outlet in SpeakLineAppDelegate.h. Set the Connection to Outlet, name it textField, and click Connect, as shown in Figure 5.12.
Figure 5.12. Control-drag to Create the textField Outlet
Xcode will create a new @property line. A property is like a setter and getter in one, however in this case there is no clear instance variable backing the property. In fact, the complier will automatically create an instance variable named _textField. How do we know this? Look for the @synthesize line in SpeakLineAppDelegate.m. We will learn more about properties in Chapter 7.
Note that if we were using the Connection panel instead of the Assistant Editor to create an outlet connection, we would be dragging from SpeakLineAppDelegate to the text field.
SpeakLineAppDelegate.h should now look like this:
#import @interface SpeakLineAppDelegate : NSObject @property (assign) IBOutlet NSWindow *window; @property (weak) IBOutlet NSTextField *textField; - (IBAction)stopIt:(id)sender; - (IBAction)sayIt:(id)sender; @end If you look at SpeakLineAppDelegate.m, you will find that Xcode has created stubs for the sayIt: and stopIt: actions. At this point, you have set all but one of the connections shown in the object diagram in Figure 5.9. The missing connection, speechSynth, will be done programmatically—not in Interface Builder. NSWindow’s initialFirstResponder Outlet When your application runs and the new window appears, users should not have to click on a text field before they type. You can tell the window which view should be receiving keyboard events when the window appears. Control-click on the window icon in the Interface Builder dock to get its Connection panel. Drag from initialFirstResponder to the text field. Implementing the SpeakLineAppDelegate Class
Now you need to write some code, so select the SpeakLineAppDelegate.h file. Add an instance variable named speechSynth of type NSSpeechSynthesizer: