Chapter    4

Buttons and Labels with Multiple Graphics

In this chapter, you’ll tackle your fourth program, and it’s time to quicken the pace a bit. As in Chapter 3, you’ll be able to simply view the screen shots and implement the code if you remember most of the details—steps that have been described repeatedly in the previous examples. You’ll get fewer figures pertaining to each step, yet more procedures; I’ll be using the short bursts of information introduced in Chapter 3.

In addition, as in Chapter 3, once you’ve completed the program, you’ll get a code review in the “Digging the Code” section. Initially, I’ll cover some of the same aspects and concepts discussed in that section in Chapter 3 and then I’ll zoom in on some of the new code. Not only will I go a little deeper, but I’ll consider other computing concepts that link up to this deeper level of analysis.

You will probably also notice a change of style in this chapter. I’ll be moving away from the “elementary” language used in previous chapters. I’ll also be doing less hand-holding for you with the images. I’ll start weaning you off arrows—all the information is there, so if you can’t immediately find what I’m referencing in the text, you’ll need to think a little and look to find it. Think of it as an exercise to force your neurons to make some associations by taking baby steps. We’re picking up the pace—a little faster, a little more advanced, and using more of the technical nomenclature.

Most importantly, at step 30 I open the hood, and you’ll really get our hands dirty, delving into some critical code concepts that you’ll need to wrap your head around in order to move on through the book. Don’t worry; I make it easy.

Again, if you don’t grasp every concept and technique fully, that’s perfectly okay. Relax and enjoy this next example. But before we start our fourth app, let’s take a brief glance at our roadmap.

Roadmap Recap

Thus far, we’ve gone through three Hello World examples. You’ve had an opportunity to familiarize yourself with the creative process in the context of programming apps: go in with an idea and come out with a tangible, working product. Several times I’ve asked you to ignore heavy-duty code that I judged would be distracting or daunting. You may have also noticed that when you did try to understand some of this thicker code, it made sense in a weird, wonderful, chaotic way. Well, as we progress, we’re going to make the chaos of the unknown less unsettling.

Before dealing with this issue, let me also put you at ease by telling you that when it comes to Objective-C, I have yet to meet a single advanced programmer who knows every symbol and command. Just as in other industries, people tend to get very knowledgeable in their specific domains and specializations (for example, integrating Google Maps to a game or an app).

Car mechanics used to be able to strip an engine down completely and then build it back up—presumably better than it was. Nowadays, car mechanics are very specialized, with only a handful knowing how to completely strip down and rebuild any given new car. You get an expert in Ford hybrid engines, Toyota Prius electrical circuitry, the drum brakes that stop big rigs, and so on. There’s nothing wrong with this.

It’s similar to how you’re proceeding. You’ve just gotten your hands greasy and dirty by successfully programming three apps. Now, if all goes according to plan, you’re going to delve even deeper when you get to step 30. Soon you’ll be brimming with confidence. I know from experience that the confidence of my students can be derailed if they’re intimidated—they can be blown away by too much complexity or technicality. I’ve found that students can handle bumps in the road if they know where they’re going, and if they know that the rough stretches won’t get too scary or dangerous.

helloWorld_04: A View-Based Application

Right this second—feel good about yourself! You’re already quite deep into the Objective-C forest. If you lose your way, remember that besides the book and its screenshots, I also offer you screencasts, available at my website. http://bit.ly/PFXJGe is the short URL, or go to rorylewis.com, click the iOS6 icon, and click either Video tutorials or Downloads.

  1. As usual, let’s begin with a clean desktop and only five icons: your Macintosh HD (if you’ve kept it visible like I do) and four image files shown as icons in Figure 4-1. As I’m sure you’ve gathered by now, I think having an uncluttered desktop is essential, and I want to encourage you to continually hone your organizational mindset. Using our familiar shortcuts, close all programs. You’re welcome to download these images from http://tinyurl.com/9r7lnuw from the Downloads page or from the Videos page at http://tinyurl.com/8rvwzdk. Icons will become key building blocks of this project, but I really want to encourage you to find and prepare images of your own. That way, you’ll have more passion about this assignment. If you create your own images, pay attention to the following guidelines.

    9781430246176_Fig04-01.jpg

    Figure 4-1.  Create or download three .png image files: a bottom layer, a top layer, and a desktop icon. Save them all to a beautiful, clean desktop

  2. The size of the first picture, STAIR.png, as shown in Figure 4-2, will be the iPhone standard of 640 pixels in width by 1096 pixels in height. This will be the bottom layer of two images, so we’ll call it the background layer. Our background, then, is a photograph of the stairs leading out the back of the Engineering Building here at the University of Colorado at Colorado Springs. We will use this picture as a backdrop for a picture of Immanuel Kant—the greatest philosopher of all time—a man whose philosophy formed the basis of that of many of our founding forefathers who framed the Constitution. More importantly to us, he was the man who began mapping parallels between mathematical logic and words in speech. When the program is run, the background will display and, once a button is clicked, up will pop the photo of Immanuel Kant at the top of the stairs. Take a quick peek at Figure 4-3. How nice—Immanuel Kant has decided to return to university! This is our scenario then: Many times in programming, you’ll find that you want your user to see a familiar background, and then when a button is tapped, somebody (or something) unusual or unexpected suddenly appears. This program helloWorld_04 will teach you how to do that.

    9781430246176_Fig04-02.jpg

    Figure 4-2.  STAIR.png is the background image—or bottom layer

    9781430246176_Fig04-03.jpg

    Figure 4-3.  This is the modified top-layer image, which will overlay the background

  3. To create the second image, which we’ll call the top layer, copy the background layer photo, which, in my case at least, was STAIR.png. Then crop this copy to create an image with these exact dimensions: 640 × 698 pixels. Yes, I know the height is a strange number—but trust me, the new Apple overlay code transforms the pixilation schema in a way that makes this weird size perfect! Now you have a roughly square copy of the bottom two-thirds of your background photo. Next, paste onto this a partial image—probably a cut-out of some interesting or unusual object. This will yield something like the image in Figure 4-3: Immanuel Kant, in front of the background scene. This modified top layer will, of course, be saved as a .png file. Thus, you will end up with a prepared top layer that consists of the bottom section of the original background photo, with some interesting person or object pasted over it. You can probably guess that you’re going to program the device to start with the background image, and then, with some user input, insert the top layer—with bottom edges matching up flush, of course. This will give the illusion that your interesting guest, or object, suddenly materialized out of nowhere. The top layer will not affect the space near the upper part of the background; you’re reserving this region for the text that you’ll also direct the device to insert.
  4. The third image file is an icon of your choice. As in the previous chapter, you may want to customize your icon. In my case, I took a portion of the photograph of Immanuel Kant‘s face and put it into my icon file, as shown in Figure 4-4. Once you have all three of these images—the bottom layer, top layer, and icon—save them onto your desktop, which will make it look similar to Figure 4-1.

    9781430246176_Fig04-04.jpg

    Figure 4-4.  This is the image for the screen icon

    Note   Remember that icons for the iPhone 5 have a recommended size of 114 × 114 pixels, as illustrated in Figure 4-4. However, note that if your app is to run on previous models of the iPhone, include a 57 × 57 version of this icon and drag it in as specified the steps coming up. Be sure to stay mindful of these dimensions.

  5. Now, just as you did in the first example, launch Xcode and open a new project by using your keyboard shortcut (image+Arrow2.jpg+N). Your screen should show the New Project Wizard, as depicted in Figure 4-5. You may find that your Single View Application template was highlighted by default; if not, click the Single View Application icon and then click Next, as indicated in Figure 4-5.

    9781430246176_Fig04-05.jpg

    Figure 4-5.  Tap image +Arrow2.jpg + N and select Single View Application from the New Project window

    You may be thinking that a View-Based Application Template is normally used to help you design an application with a single view and that you should pick another option—because you’ve just made two views, the image of the stairs and the modified image of the stairs with Immanuel Kant in it. This reasoning would appear to be sound except that this is actually not the case here—it really still is a single view. Think of it this way: You’ll be dealing with only one perspective, onto which you’ll superimpose an image, not a view. If you were going to have portions of your code in one navigation pane and other portions in other navigation panes, then you’d probably choose a Navigation-Based Application. In this current project, though, you’re going to manipulate one view in which you’ll superimpose images rather than navigate from one pane to another. In essence, you’ll be playing tricks with a single view.

  6. Because this is the fourth helloWorld, name it helloWord_04, as shown in Figure 4-6

    9781430246176_Fig04-06.jpg

    Figure 4-6.  Name your project and define it as an iPhone project

  7. Save your View-Based Application to your desktop as helloWorld_04 (as shown in Figure 4-7). This will be the last of your Hello World apps. Once you’ve completed this program, save all of them in a Hello World folder inside your Code folder. You’ll probably find yourself going back to these folders at some point to review the code.

    9781430246176_Fig04-07.jpg

    Figure 4-7.  Save it to your desktop

    .

    Later in the book, when I go into the details of Objective-C and Cocoa, there is a good chance that you’ll scratch your head and say, “Damn—that sounds complicated, but I know I did this before. I want to go back and see how I connected these files in those Hello World exercises I did at the beginning of this book.”

  8. First, you’ll drag icons into the project. Select your 57 × 57 icon.png file and place it into the slot immediately to the left of the Retina Display icon slot. Then drag your 114 × 114 icon.png and place it into the Retina Display slot. Figure 4-8 shows the 57 × 57 icon.png  in its place next to the 114 × 114 icon.png being dropped into position.

    9781430246176_Fig04-08.jpg

    Figure 4-8.  Drag your three icons into the project

  9. Now drag your two images (KANT.png and STAIR.png) into your Supporting Files folder. As you probably know by now, Xcode has instantiated a project named helloWorld_04, as shown in Figure 4-9. Note that when the folder highlights, it means that the object is selected. Focus on where your mouse pointer is—that’s the point at which the folder will react. Once it highlights, drop the object in by releasing the mouse button. Sometimes students get confused because it seems that the images should be able to drop into the folder, but it won’t highlight. This’s because the folder opens, or highlights, only when your mouse pointer carrying all the pictures hovers over the folder. So, remember that when you’re dragging objects over to the folders, focus on where your mouse pointer is and ignore everything else.

    9781430246176_Fig04-09.jpg

    Figure 4-9.  Drag your two images into the project

  10. After dropping the image into the Resources folder, you’re prompted to define whether the image will always be associated with its position on your desktop or whether it will be embedded with the code and carried along with the application file, as shown in Figure 4-10.

    9781430246176_Fig04-10.jpg

    Figure 4-10.  Check the “Copy items into the destination group’s folder” box

    You want it to be embedded, of course, so click the “Copy items. . .” box. Also check the “Create groups for any added folders” box. Then click Finish (or tap Enter).

  11. Icons are housed in the blue helloWorld_04, 1 target iOS SDK 6.0 folder at the top of the page. You want to get into the habit of making sure that all your images all always in the Supporting Files folder, so drag them from the blue folder into the Supporting Files folder, as shown in Figure 4-11.

    9781430246176_Fig04-11.jpg

    Figure 4-11.  Drag icons into the Supporting Files folder

  12. Click your nib file, as illustrated in Figure 4-12, because it’s time to start building the objects you’ll need for your project. You should be seeing a pattern now: first you dump our images into the Resources folder, then you drag our objects onto the view, and finally you link the objects up with code.

    9781430246176_Fig04-12.jpg

    Figure 4-12.  Open your nib file

  13. Your top layer image will be placed over the base layer when the user taps the button. Therefore, you want to handle the base layer in the same manner as you have in the past. Scroll down in your Library to the Cocoa Touch objects folder and locate the Image View icons. Drag one onto your View frame, as illustrated in Figure 4-13.

    9781430246176_Fig04-13.jpg

    Figure 4-13.  Position the UIImageView onto the View screen, flush with the bottom

  14. You want to connect the 640 × 1096 STAIR.png to your Image View so that it will appear. Go to the Information tab of the Image View Attributes window, open the drop-down window, and select the image, as shown in Figure 4-14.

    9781430246176_Fig04-14.jpg

    Figure 4-14.  Associate an image with UIImageView, which you’ve just dragged onto the View screen

  15. Earlier, I said that when the user taps the button, Immanuel Kant should appear and announce, “Hello World I’m back!” The method you’ll employ here will be a label instance variable—with a text property assigned with “Hello World I’m back!” So, drag out a label that will be your instance variable (see Figure 4-15), and you’ll assign the text “Hello World I’m back!” onto the base view later. When you put the label onto the view, repeat the way that you adjusted the size in the earlier assignments; that is, widen it so it can fit this text.

    9781430246176_Fig04-15.jpg

    Figure 4-15.  Drag a label onto the view

  16. Just as you’ve done before, center the text, change its color to white in the Properties frame, and delete the default text “Label.” In Figure 4-16, note that the center text has been selected and I am just about to change the black text.

    9781430246176_Fig04-16.jpg

    Figure 4-16.  Center and delete the text

  17. You want the picture and the text to appear when a button is tapped, which means you need a button. Go ahead and drag one onto your base layer, as shown in Figure 4-17, and in its Title field enter Guess who’s back in town? When users see a button asking this question, they will be compelled to tap it. When they do, you want Immanuel Kant to appear, saying, “Hello World, I’m back!” You may want to adjust the size of the button as you’ve done before. If you’re inclined to make your button fancier than the one I created in the video, you may want it to show some of the underlying image. While still in the Image View Attributes window, scroll down and shift the Alpha slider to about 0.30. Jumping ahead, you may want to start thinking about what you’re doing in terms of the code you’ll soon write. We’re looking at two IBOutlets: a label and the underlying base image. Each category “whispers” something to Interface Builder. One says that you want a UILabel class to use text that the pointer *label points to; the other says that the UIImageView class will put up an image located at a place the pointer *uiImageView points to.

    9781430246176_Fig04-17.jpg

    Figure 4-17.  Drag a button onto your base layer

    Well, what have you done so far in Interface Builder? You’ve installed the background image and inserted a button that will trigger these two IBOutlets. Now, while still taking a minute to think ahead about what happens each time you drag outlets onto your header file, let’s take a high-altitude view of what you’ll be doing here:

    - (IBAction)someNameWeWillGiveTheButton:(id) sender

    That line, in fact, invokes your two friends—the two IBOutlets for the label and background image—for the label, with

    label.text = @"Hello World, I'm back!";

    and the image, with

    UIImage *imageSource = [UIImage imageNamed: @"Kant.png"];

    To make all that work in the implementation file, you need to perform some action on the header file. You have to set the label and the image up—which is called declaring them.

    You’ll declare the label with this:

    IBOutlet UILabel *someNameWeWillGiveTheLabel

    And you’ll declare the image with this:

    IBOutlet UIImageView * someNameWeWillGiveTheImageView

    Okay, that was a quick mental journey into the future. Now you’re ready for action. You’ve created a button that will call your two friends; all you need to do now is create the image and the label and then associate them with the appropriate pieces of code.

  18. You need the button to entice the user to tap it. So you’ll ask the user “Guess who’s back in town?” by double-clicking the button and writing the text in it. You may notice that the button cleverly adjusts its size to accommodate the text width (Figure 4-18).

    9781430246176_Fig04-18.jpg

    Figure 4-18.  Write the button text

  19. Think about this for a second now. When the button is tapped, you want the kantStair.png image to appear on top of the background, STAIR.png. How does it get there? It’s carried onto the screen by way of an Image View. Therefore, drag an Image View onto the screen, as shown in Figure 4-19. Then place it flush to the bottom edge of the iPhone/iPad screen. You don’t want the image floating in the middle of the screen, but rather appear as if it’s projecting from the bottom. Once you’ve dragged the image to the screen, just let it go. You haven’t configured its size or placement. That’s next.

    9781430246176_Fig04-19.jpg

    Figure 4-19.  Drag the second image view onto the view

  20. In the Image View Attributes Inspector, click the View tab. The View mode Scale to Fill is selected by default. You want to change that to Bottom, as illustrated in Figure 4-20. Before moving on to the next step, take a minute to align the label and button with each other, and in context with the center of the screen, as depicted in Figure 4-20.

    9781430246176_Fig04-20.jpg

    Figure 4-20.  Adjust the location of the second Image View

    You’re now done with dragging items out onto the View. You have your label, a button, and two Image Views. Now save everything, and you’ll start putting some code behind these items you’ve dragged onto the view.

  21. You now want to start tweaking your screenview to accommodate code. As in the three earlier apps, you’ll start moving from the Interface Builder View to our Coding View by clicking the Assistant, as depicted in Figure 4-21.

    9781430246176_Fig04-21.jpg

    Figure 4-21.  Click the Assistant

  22. Select the button in preparation for Control-dragging it over to the header file (see Figure 4-22). Don’t drag it yet; you have to look at IBOutlets and IBActions a little more first.

    9781430246176_Fig04-22.jpg

    Figure 4-22.  Select the button

    Understanding IBOutlets and IBActions

    In previous chapters, I discussed the .m and .h extensions in detail. You’ve been doing what most Cocoa and Objective-C programmers do: Start off by programming the header files. In geekspeak, you’d say, “After dragging out objects onto the view, I opened the header and Control-dragged the IBOutlets and IBActions into the header file.” If anybody were to ask you on a forum to explain, you may tell them, “Click the disclosure triangle in your Classes file and open the ViewController.h file.”

    You’ve already programmed three previous header files, so you should be accustomed to just flying over this portion of your code. But this time you’re going to hit the brakes and think about what you’re doing. For all your previous examples, you’ve only had to use one IBOutlet, a thing that allows you to interact with the user. Let’s get more technical and specific and dig deeper into what an IBOutlet is so that when you get to the “Digging the Code” section, you’ll be able to really understand it. But before digging the code, you need to hook up your IBActions and IBOutlets knowing that you’ll go deep into the code that Xcode instantiates for you as you connect the labels and buttons to your header file.

    9781430246176_Fig04-23.jpg

    Figure 4-23.  Control-drag a connection from your button in Interface Builder into your header file

  23. Control-drag your button to the area below the @interface directive, as shown in Figure 4-23.
  24. Change the connection type in the top drop-down menu in the dialog box from Outlet to Action, as shown in Figure 4-24.

    9781430246176_Fig04-24.jpg

    Figure 4-24.  Open the drop-down menu and change the type of connection to Action

  25. You now need to name this action. You could name it monkey or anything you like, but call it button, as shown in Figure 4-25.

    9781430246176_Fig04-25.jpg

    Figure 4-25.  Name the Action type button

  26. As shown in Figure 4-26, after clicking the label once in Interface Builder, Control-drag it into your header file. Make sure you keep on Control-dragging until you see the insertion indicator, as shown in Figure 4-26.

    9781430246176_Fig04-26.jpg

    Figure 4-26.  Control-drag from the label to your header file

  27. As shown in Figure 4-27, when you’ve Control-dragged your label out to the @interface directive, drop it there, call it label, and leave the Connection type as Outlet.

    9781430246176_Fig04-27.jpg

    Figure 4-27.  Let’s name the label outlet “label”

  28. After clicking the second UIImageView in Interface Builder, Control-drag it until you see the insertion indicator, as shown in Figure 4-28. Make sure that when you Control-drag into your header file, you go directly under the label outlet you just created.

    9781430246176_Fig04-28.jpg

    Figure 4-28.  Control-drag a connection from your second UIImageView in Interface Builder into your header file

  29. As shown in Figure 4-29, when you’ve Control-dragged from the second UIImageView out to the @interface directive, drop it there, call it kant, and leave it as an Outlet Connection type.

    9781430246176_Fig04-29.jpg

    Figure 4-29.  Name the second UIImageView outlet kant

  30. The following is the code in your header file (Figure 4-30 shows it in context). You seek a deeper understanding of these elements:
    #import <UIKit/UIKit.h>
    @interface ViewController : UIViewController
    - (IBAction)button:(id)sender;
    @property (retain, nonatomic) IBOutlet UILabel *label;
    @property (retain, nonatomic) IBOutlet UIImageView *kant;
    @end

    9781430246176_Fig04-30.jpg

    Figure 4-30.  Save your work

    Let’s start with the first line:

    #import <UIKit/UIKit.h>

    This is what permits you to use the IBOutlet keyword. You use #import to import the UIKit, which is the user interface (UI) framework inside the huge body of core chunks of code called IPhoneRuntime, which is a stripped-down version of the OS X operating system found on a Mac. Of course, IPhoneRuntime is smaller so it works on an iPhone or an iPad.

    When you import the UIKit framework, it gives you the ability to use tons of code Apple has already written for you—called classes—one of which is the very cool and popular class you’ve already used: IBOutlet. The IBOutlet keyword is a special directive for what’s called an instance variable; this directive tells Interface Builder to display items that you want to appear on the iPhone or iPad. In turn, Interface Builder uses these “hints” to tell the compiler that you’ll be connecting objects to your .xib files. Interface Builder doesn’t connect these outlets to anything, but it tells the compiler that you’ll be adding them.

    Here’s an inventory of what you’ll be using:

    • The background image of the stairs
    • The top-layer image of Kant
    • The text of what he will say upon his return to the campus

    In the next exercise, you’ll be using two IBOutlets—one dealing with the text in the label where Kant says “Hello World, I’m back!—and the other with your second view where Kant magically appears. Knowing that you need two IBOutlets, you can visualize how it will look. The IBAction and IBOutlets are in bold. Start by focusing on the code that follows @interface ViewController : UIViewController. Your code will need to appear as follows:

    #import <UIKit/UIKit.h>
    @interface ViewController : UIViewController
    - (IBAction)button:(id)sender;
    @property (retain, nonatomic) IBOutlet UILabel *label;
    @property (retain, nonatomic) IBOutlet UIImageView *kant;
    @end

    You know that when you shoot text onto the iPhone or iPad screen, you use the UILabel class. This class draws multiple lines of static text. Now, consider what you’ll need for the second IBOutlet. You know you want to impose the top layer image, as shown in Figure 4-3. A good idea here would be to use the UIImageView class because it provides you with code written by Apple that can display either single images or a series of animated images. As you can see, it now makes sense to say you have two IBOutlets:

    • Let one call the UILabel class to control the text.
    • Let the other call the UIImageView class to control the second image.
    #import <UIKit/UIKit.h>
    @interface ViewController : UIViewController
    - (IBAction)button:(id)sender;
    @property (retain, nonatomic) IBOutlet UILabel *label;
    @property (retain, nonatomic) IBOutlet UIImageView *kant;
    @end

    Using pointers

    Now that you have the means to push text and an image to the screen, you need to specify which text and which image. You can use predefined code, created by the folks at Apple, which does what it does by virtue of referencing or pointing to your resources—that is, your text and images. This is the context in which you’ll be using pointers.

    In previous examples, I told you not to worry about that star thing (*) yet. Well, now it’s time to take a look at it. Let’s focus for a moment on how these (*) things—pointers—do what they do. You need an indirect way to get your text and picture onto the screen because you won’t be writing the code to do it—you’ll use Apple’s code to do it. You call up pre-existing classes, and these classes call up your text and your image. That’s why I say it’s an indirect means of obtaining your stuff.

    Consider this little analogy: suppose you make a citizen’s arrest of a burglar who breaks into your house. You call the police and, when they arrive, you point to the criminal and say, “Here’s the thief!” Then the policeman, not you, takes the criminal away to be charged.

    Now, you want to display text on your iPhone/iPad. You call UILabel, and when it “arrives,” you point to your words and say, “Here’s the text.” Then the UILabel, not you, deals with the text.

    You do likewise when you want to display an image. You call UIImageView, and when it “arrives,” you point to your image and say, “Here’s the image.” Then the UIImageView code, not you, deals with the picture.

    What are these pointers called? You can give them whatever names you want. Let’s point the UILabel to *label and the UIImageView to a pointer called *kant. Look at the code you’ve just written:

    #import <UIKit/UIKit.h>
    @interface ViewController : UIViewController
    - (IBAction)button:(id)sender;
    @property (retain, nonatomic) IBOutlet UILabel *label;
    @property (retain, nonatomic) IBOutlet UIImageView *kant;
    @end

    Some of the clever people at Apple describe their reasoning for creating and coding IBOutlets as giving a hint to Interface Builder into what it should “expect” to do when you tell it to lay out your interface.

    • One IBOutlet whispers into Interface Builder’s ear that the UILabel class is to use text indicated by the *label pointer.
    • The other IBOutlet whispers into Interface Builder’s ear that the UIImageView class is to use the image referenced by the *kant pointer.

    You’re not done yet. After you tell Interface Builder what to expect, you need to tell your Mac’s microprocessor—through the compiler—that an important event is about to descend upon it. Your compiler always wants to know when an object is coming its way. That’s because objects are independent masses of numbers and symbols that put significant demands on the microprocessor, and the processor needs to be told by you—the programmer—when it needs to catch the object and put it into a special place in memory.

    Objects can come in a wide variety of flavors, as conceptually different as bird, guru, soccer, and house. To enable the processor to handle its job when the time comes, you need to tell it that each object you’ll be using in your code has two specific and unique parameters, or features: they’re called property and type.

    Don’t freak out! Providing this information is really easy. It consists of two steps.

    The first step is what you just read about: you give the compiler a heads-up about the objects you’ll be using by defining their property and type. The second step that when the microprocessor receives this data, it utilizes this information by synthesizing it.

    To summarize:

    • First you declare that your object has a property with a specific type.
    • Second you instruct the computer to implement—or synthesize—this information.

    You tell the compiler about your object by declaring it, including giving the specific descriptive parameters of its properties. Then you give the compiler the go-ahead to implement your object by telling it to synthesize it.

    How do you do this declaring and implementing? Using tools in your code called directives. You signal directives by inserting @ before stating your directive. You put the @ symbol in front of the word property to make it a property directive: @property.

    Easy, huh? Just two more points now, and then you’ll get back to your code.

    Properties: Management and Control

    You also need to specify whether a property will be read-only or read-write. In other words, you need to specify whether it will always stay the same or whether it can mutate into something new. In geekspeak, we call this mutability. For the most part, you’ll use Apple code to handle the mutability of properties with respect to your objects.

    To instruct the Apple code to handle the mutability property, you designate the property as nonatomic. Atomicimplies the ability to go into the microscopic world and effect change. Nonatomic must mean not-so-powerful, more superficial, and unmanipulable.

    If you designate a property (such as mutability) as nonatomic, you’re basically saying, “Apple, please handle my mutability and related stuff—I really don’t care. I’ll take your word for it.” At a later date, you may want to take direct control of this property, and then you’d designate it as atomic. Right now, though, you’ll use the more relaxed approach and let Apple handle the microscopic business. So, when it’s time to choose one designation or the other, just use nonatomic.

    The other point I want to make deals with memory management. You need to address the issue of how to let the iPhone/iPad know, when you store an object, whether it is read-only or read-write. In other words, you need to tell the computer the nature of the memory associated with an object—who gets to change it, when, and how. Generally speaking, you want to control and keep this information—that is, retain it. As you move through the remaining exercises in this book, you’ll keep the code in your own hands and retain the right to manage your memory.

    #import <UIKit/UIKit.h>
    @interface ViewController : UIViewController
    - (IBAction)button:(id)sender;
    @property (retain, nonatomic) IBOutlet UILabel *label;
    @property (retain, nonatomic) IBOutlet UIImageView *kant;
    @end

    To summarize, the @property (nonatomic, retain) directive says the following:

    • Mutability should be nonatomic. Apple, please handle this!
    • Memory management is something you want to retain. You will maintain control.

    Remember IBOutlets? Oh yeah—let’s return to that part of your program. The IBOutlet for the text is UILabel with pointer *label, so you created the code to control the text for the label as follows:

    #import <UIKit/UIKit.h>
    @interface ViewController : UIViewController
    - (IBAction)button:(id)sender;
    @property (retain, nonatomic) IBOutlet UILabel *label;
    @property (retain, nonatomic) IBOutlet UIImageView *kant;
    @end

    The IBOutlet for the picture is UIImageView with the pointer *kant, so enter the code for the picture:

    #import <UIKit/UIKit.h>
    @interface ViewController : UIViewController
    - (IBAction)button:(id)sender;
    @property (retain, nonatomic) IBOutlet UILabel *label;
    @property (retain, nonatomic) IBOutlet UIImageView *kant;
    @end

    Are you done with the header file yet? Not quite. You need to look at your IBActions. You’ve analyzed both your IBOutlets, but now you’re going to analyze the IBAction you used for your . . . can you guess?

    Adding IBActions

    Yes, you needed a button! So you made an IBAction for your button, as shown in Figure 4-25. We could “go deep” again, into the code for the IBAction, but this has been a challenging section. Let’s save the technical part of this element for the “Digging the Code” section. Meanwhile, just enter the new code that’s highlighted here. See if you can anticipate the functions of the different pieces—or parameters—and you’ll see how close you are later.

    This is what you’ll be focusing on:

    #import <UIKit/UIKit.h>
    @interface ViewController : UIViewController
    - (IBAction)button:(id)sender;
    @property (retain, nonatomic) IBOutlet UILabel *label;
    @property (retain, nonatomic) IBOutlet UIImageView *kant;
    @end

GO OUT NOW AND TAKE A BREAK

  • 31.  Right now, the Interface Builder is showing your nib file. Save everything, go to your Navigator, and click the implementation file (.m), as shown in Figure 4-31.

    9781430246176_Fig04-31.jpg

    Figure 4-31.  Save your work and open the implementation file

  • 32.  Look at the code Apple has instantiated for us (see Figure 4-32 to see where it appears).  Look at these three lines in bold first:

    9781430246176_Fig04-32.jpg

    Figure 4-32.  With the implementation file open, you can now code

    #import "ViewController.h"
    @interface ViewController ()

    @end

    @implementation ViewController

    - (void)viewDidLoad ...
    - (void)didReceiveMemoryWarning ...
    - (IBAction)button:(id)sender {} ...
    - (void)dealloc {} ...

    @end

    You can see that the implementation file first imports all the code of the iBOutlets and IBActions you created from your header file using the #import "ViewController.h" statement.  Next you’ll see the @interface ViewController () and, of course, you’ll ask why do you see @interface twice—once inside the header .h and then again inside the .m over here? This is going a little deep here—don’t worry if you don’t understand it; just let it drift through your brain:  This @interface in your .m file is something called a class extension. In other words, your class implementation is identified by two compiler directives—here, @implementation (for the View Controller) and @end. These directives provide extra information the compiler needs to associate the enclosed methods with the corresponding class. But as I said, don’t worry about this now—Apple just does it for you.

    Let’s quickly review what else you have by looking at the two methods (void)viewDidLoad and - (void)didReceiveMemoryWarning. Refer to Apple’s comments for each of these. - (void)viewDidLoad is the place to code any additional setup after loading the view, typically from a nib, and - (void)didReceiveMemoryWarning is the place where you dispose of any resources that can be re-created:

    #import "ViewController.h"
    @interface ViewController ()
    @end
    @implementation ViewController

    - (void)viewDidLoad
    {
        [super viewDidLoad];
            // Do any additional setup after loading the view, typically from a nib.
    }

    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }

    - (IBAction)button:(id)sender {} ...
    - (void)dealloc {} ...

    @end

    I’ll focus on the method that controls what happens when the user taps the button you created, - (IBAction)button:(id)sender. The –(void) dealloc method just deallocates the memory you need to use to run what’s inside it:  _label, _kant, and super (everything we missed). Note that adding an underscore (_) to an instance variable name is a common convention in Objective-C. Figure 4-32 shows me typing in the first word in this section, label, in anticipation of the next step.

    #import "ViewController.h"
    @interface ViewController ()
    @end
    @implementation ViewController

    - (void)viewDidLoad ...
    - (void)didReceiveMemoryWarning ...

    - (IBAction)button:(id)sender {}

    - (void)dealloc {} ...
    @end
  • 33.  As indicated in Figure 4-33, you’re now ready to program the code that will execute when the user taps the button. In other words, you’re ready to program the button’s code. Scroll down until you get to the button method that exists but is currently empty.

    9781430246176_Fig04-33.jpg

    Figure 4-33.  Write the first two lines of the button method

    When the user runs this app and taps the button, the image of Kant will appear instantly on top of the background staircase. He’s going to “say” something via the embedded text. As noted earlier, let’s go with, “Hello World I’m back!” To accomplish this, you need to associate the label instance variable with a text property assigned with your desired text, as follows:

    #import "ViewController.h"
    @interface ViewController ()
    @end

    @implementation ViewController
    - (void)viewDidLoad {[super viewDidLoad];}

    - (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];}

    - (IBAction)button:(id)sender {
        _label.text = @"Hello World I'm back!";
        UIImage *imageSource = [UIImage imageNamed:@"Kant.png"];
        _kant.image = imageSource;
    }

    - (void)dealloc {[_label release]; [_kant release]; [super dealloc];}
    @end

    Note   When reading declarations, the : is shorthand for subclasses, and the <> is shorthand for implements.

    Having completed the task of coding for the text, you now need to add the code that will cause the image of Kant to appear. For that, you’ll use a class method called imageNamed that will display the kant.png image, the top-layer photo you prepared at the beginning of this project. Enter the line in bold in the following code immediately under the code you just entered for the text:

    #import "ViewController.h"
    @interface ViewController ()
    @end

    @implementation ViewController
    - (void)viewDidLoad {[super viewDidLoad];}

    - (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];}

    - (IBAction)button:(id)sender {
        _label.text = @"Hello World I'm back!";
        UIImage *imageSource = [UIImage imageNamed:@"Kant.png"];
        _kant.image = imageSource;
    }

    - (void)dealloc {[_label release]; [_kant release]; [super dealloc];}
    @end

    Your pointer’s name for the image is Kant, but right now the kant.png image file is in UIImage’s assigned pointer called imageSource. You need to assign this automatically assigned pointer imageSource to the image of Kant, as shown in the following code:

    #import "ViewController.h"
    @interface ViewController ()
    @end

    @implementation ViewController
    - (void)viewDidLoad {[super viewDidLoad];}

    - (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];}

    - (IBAction)button:(id)sender {
        _label.text = @"Hello World I'm back!";
        UIImage *imageSource = [UIImage imageNamed:@"Kant.png"];
        _kant.image = imageSource;
    }

    - (void)dealloc {[_label release]; [_kant release]; [super dealloc];}
    @end

    If that doesn’t quite make sense at the moment, that’s okay. There sure are a lot of entities with image as part of their name, object, or association, and it’s confusing. You’ll be examining this topic more thoroughly as you move forward, so, right now, don’t lose any sleep over it. Figure 4-33 illustrates how your code should appear at this point. Now save your work by pressing image+S and give yourself a pat on the back. You’ve worked through the header and implementation files at a much deeper level than in previous chapters. Even though you’ve walked through some of these technical functions before, you braved them again while remaining open to a deeper understanding.

  • 34.  Now that you’re through writing your code, run it and see if you have any errors (Figure 4-34).

    9781430246176_Fig04-34.jpg

    Figure 4-34.  With the code all written, let’s run it

  • 35.  Figure 4-35 illustrates the two views of helloWorld_04. Your images will be different, of course, if you used your own. The first view is what the user sees when the app first opens. The second image is what appears when the button is tapped. The label text appears, and the second image is superimposed on top of the underlying image.

    9781430246176_Fig04-35.jpg

    Figure 4-35.  The two helloWorld_04 views

Digging the Code

In this section, let’s zoom in on some of the key components you encountered earlier in this chapter. I want to talk a little more about IBOutlets and IBActions—specifically, how they include keywords and even quasi-keywords. I also touch on pointers and their relationship to addresses in the code.

IBOutlets and IBActions

Earlier, you worked with IBOutlet and IBAction keywords. Now I’m going to talk about a couple related concepts.

The Appkit of Objective-C converts original C language preprocessor directives such as #define (pronounced “pound define”) into usable preprocessor directives.

Note   In the United States, the # sign is often called the pound sign, especially in Objective-C and other programming contexts. In the United Kingdom, it’s referred to as the hash character. Many iPhone/iPad developers refer to the #define preprocessor directive simply as the define directive.

The #define preprocessor directive tells the computer to substitute one thing for another. That’s an easy concept, right? For example, if I program the computer to substitute 100 every time it sees an instance of your name, the code in C would look like this:

#define yourName 100

This would tell the computer to substitute 100 each time it processes yourName—a variable that recognizes instances of your actual name.

Back to Xcode now, and our topic. In this context, the IBOutlet and IBAction quasi-keywords aren’t really defined to be anything. In other words, they don’t do anything substantial for the compiler, which is the core of the computer.

Quasi-keywords are flags, though, and they’re important to communication with the Interface Builder. When the Interface Builder sees the IBOutlet and IBAction quasi-keywords, it gets some of its internal code ready to perform specific tasks. It gets itself ready to deal with instance variables and all the hooks and connections that we make in that programming arena.

More About Pointers

Understanding the concept of pointers—also sometimes known as the concept of indirection—is difficult for many programming students. Explaining the idea isn’t easy because it’s one of the most sophisticated features of the C programming language.

Earlier in this chapter, I presented the analogy of seeing a criminal doing something and then calling the police and pointing the police to where he is—so they, not you, can arrest the criminal. The analogy works for many students, but now let’s go a little deeper.

If you ask a computer science professor what a pointer is, he’ll probably say something like, “Pointers hold the address of a variable or a method.”

“The address?” you ask. Well, consider this new analogy. Have you ever seen a movie in which a character is traveling all over the place, looking for clues to the treasure map, or the missing painting, or the kidnapped daughter? Sometimes they spot a clue—a fingerprint, receipt, or envelope containing a cryptic message—and these take the people one step closer to their goal of finding the missing objects themselves.

We can call these clues pointers; they point to the next place to go for the solution of the given problem. They don’t necessarily give the ultimate address where everything is handled and resolved, but they give intermediate addresses or places to continue our work.

Thus, what the professor of computer science means is that pointers do not actually contain the items they direct us to; they contain the locations within the code—the addresses—of the desired objects or actions or entities. This important feature makes the C family of languages very powerful.

This simple idea makes turning complex tasks into easy ones very efficient. Pointers can pass values to types and arguments to functions, represent huge masses of numbers, and manipulate how to manage memory in a computer. You may be thinking that pointers are similar to variables in the world of algebra. Exactly!

In our first analogy, a pointer enabled an unarmed citizen to arrest a dangerous criminal by using indirection—that is, by calling the police to come and solve the problem.

Consider an example where a pointer directs us to your bank balance. To do this, define a variable called bankBalance as follows:

int  bankBalance = $1,000;

Now, let’s throw another variable into the mix and call it int_pointer. Let’s also assume that, for argument’s sake, you’ve declared it. This lets you use indirection to indirectly connect to the value of bankBalance by this declaration:

int  *int_pointer;

The *, or asterisk, tells the family of C languages that your variable int_pointer is allowed to indirectly access the integer value of the amount of money in your variable (placeholder): bankBalance.

I want to remind you that our digging around here is not an exhaustive or rigorous exploration into these topics. It’s just a fun tangent into some related ideas. At this point, there’s no reason for you to be bothered if you don’t fully understand pointers. Seeds have been planted, and that’s what counts for now!

Model-View-Controller

As mentioned previously, the programmers who developed Cocoa Touch used a concept known as the Model-View-Controller (MVC) as the foundation for iPhone and iPad app code. Here is the basic idea:

  • Model: This holds the data and classes that make your application run. It’s the part of the program where you might find sections of code I told you to ignore. This code can also hold objects that represent items you may have in your app (for example, pinballs, cartoon figures, names in databases, or appointments in your calendar).
  • View: This is the combination of all the goodies users see when they use your app. This is where your users interact with buttons, sliders, controls, and other experiences they can sense and appreciate. Here you may have a Main View that’s made up of a number of other views.
  • Controller: The controller links the model and the view together while always keeping track of what the user’s doing. Think of this as the structural plan—the backbone—of the app. This is how you coordinate what buttons the user taps and, if necessary, how to change one view for another, all in response to the user’s input, reactions, data, and so on.

9781430246176_Fig04-36.jpg

Figure 4-36.  The Model-View-Controller (MVC)

Consider the following example that illustrates how you can use the MVC concept to divide the functionality of your iPhone/iPad app into three distinct categories. Figure 4-36 shows a representation of your app. You can see that the VIEW displays a representation—a label—of “Your very cool fantastic App Includes 3 layers: A, B and C.”

In the CONTROLLER section of the app, you see the three individual layers separated out: Layer “A,” Layer “B,” and Layer “C.” Depending on which control mechanism the user taps in the VIEW domain, the display the user sees, the CONTROLLER returns the appropriate response—the next view from the three prepared layers.

Your app will probably utilize data of some type, which is stored in the MODEL section of your program. The data could be phone numbers, players’ scores, GPS locations on a map, and so on.

As the user interacts with the VIEW section, the app may have to retrieve data from your database. Let’s say your data contains the place where your user parked her car. When the user taps a particular button, the app may retrieve the GPS data from the MODEL. If it’s a moving target, it may also track changes in the user’s position in relation to a car in the parking lot. Lastly, the CONTROLLER may change the state (or mode) of your data. Maybe one state shows telephone numbers, and another shows GPS positions or the top ten scores in a game. The CONTROLLER is also where animation takes place. What happens in the animation can affect and perhaps change the state in your MODEL. You could do this by using various tools, such as UIKit objects, to control and animate each layer, state, and so on.

If this sounds complicated, bear in mind that you’ve already done much of this without even knowing it! In the first app, you had the user tap a button, and up popped a label saying “Hello World!” See? You’ve already built an interaction with a ViewController. We’ll be delving further into these possibilities, of course.

I’ll do my best to keep you focused on the big picture when it comes to interactions . . . via navigation. Our goal will be to have the user move from less specific information to more specific information with each new view.

Chapter 5 moves to the next level of complexity: Switch View Applications. You’ll see how a team of characters or roles within your code work together to direct an outcome, or series of outcomes, that gives the user the sense of seamless flow.

You’ll learn about delegators and Switch View Controllers, classes and subclasses, and lazy loads. You’ll get into the nitty-gritty of the xib files, examine the concept of memory deallocation, and learn about imbedded code comments. It’s getting curiouser and curiouser. . .

Onward to the next chapter!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset