Learn Objective-C on the Mac - Mark Dalrymple [134]
Now, edit the LOLmaker_AppDelegate.h file to add the bold lines shown below.
Then, edit LOLmaker_AppDelegate.m, adding the following line near the top so that we can use the LOLView class:
Add the following lines to the @implementation section to complete the properties:
These properties will be used with Cocoa Bindings to let the user drag in an image and type in some text which will be automatically attached to our controller object, which in turn updates the view. You’ll notice that we’re importing a LOLView.h header file and declaring an instance variable of type LOLView*, even though the LOLView class hasn’t been completed yet. Solve that problem right away by creating another new set of class files, this time for LOLView, an NSView subclass.
We’ll implement LOLView in just a few minutes, but for now let’s go configure the GUI. Double-click MainMenu.xib to bring it up in Interface Builder, and use the Library to drag a custom view, an image well, and a text field into the empty window. Use the Identity Inspector to set the class of the custom view to LOLView, and the Attributes Inspector to turn on the Editable checkbox for the image well. Finally, connect the app delegate’s lolView outlet to the LOLView in the window. When everything is laid out, your window should resemble Figure 13-9.
Figure 13-9. The layout of our LOLmaker window
This window will let the user drag in an image (to the drag well) and type in a message that will be displayed over the image. The LOLView will notice the dragged-in image and edited text, and trigger a redisplay of itself, through the use of Cocoa Bindings. The first half of the bindings will be configured in Interface Builder, the second half in code.
First, select the image well and switch to the Bindings Inspector. Create a binding for the Value attribute, selecting the app delegate in the popup list and typing image into the Model Key Path field. Then select the text field, and create a binding for its Value attribute, again selecting the app delegate in the popup list and this time typing text into the Model Key Path field.
That takes care of the bindings for the controls, but because Interface Builder doesn’t know about LOLView and what its bind-able values are, we have to set up its bindings in code. Go back to Xcode, and edit LOLmaker_AppDelegate.m, adding the following method to the @implementation section:
That takes care of the basic communications between all the objects in this application. User edits to the controls in the window are passed along to the app delegate, and from there they’ll be passed along to the LOLView, all through Cocoa Bindings. The “plumbing” of our app is now complete!
LOLView
So, how about the LOLView itself? For starters, it’s going to have a couple of properties, just like the properties that the app delegate has, to contain the values that are coming from the user. In this case, however, we want to trigger a redisplay every time one of the values changes, so that the LOLView will be redrawn. Therefore, we implement the setter methods ourselves, instead of just using the default setters generated by @synthesize. Note that we’re still using @synthesize, but our explicitly implemented setters trump the automatic ones, leaving just the automatically generated getters in place. Add the following to LOLView.h and LOLView.m, as indicated:
In those setter methods, you may notice that we’re once again going through the trouble of releasing the old value and retaining the new one, a series of steps that won’t really do anything in our garbage-collected world. Really, setText: is doing a copy rather than a retain,