iOS Programming: The Big Nerd Ranch Guide, 3/e (Big Nerd Ranch Guides) (6 page)

Read iOS Programming: The Big Nerd Ranch Guide, 3/e (Big Nerd Ranch Guides) Online

Authors: Aaron Hillegass,Joe Conway

Tags: #COM051370, #Big Nerd Ranch Guides, #iPhone / iPad Programming

BOOK: iOS Programming: The Big Nerd Ranch Guide, 3/e (Big Nerd Ranch Guides)
8.93Mb size Format: txt, pdf, ePub

Notice the
???
is now centered in the bottom label. Now center the text in the top label. (There’s no text now, but there will be in the running application.)

 

Your application’s interface now looks like it should, but before we start writing code, let’s dive into some programming theory.

 
Model-View-Controller

You may hear iOS programmers mention the Model-View-Controller pattern. What this means is every object you create is exactly one of the following: a model object, a view object, or a controller object.

 

View objects
are visible to the user. In
Quiz
, the buttons, labels, and the view they are placed on top of are all view objects. Views are usually standard
UIView
subclasses (
UIButton
,
UISlider
), but you will sometimes write custom view classes. These typically have names like
DangerMeterView
or
IncomeGraphView
.

 

Model objects
hold data and know nothing about the user interface. In this application, the model objects will be two lists of strings: the
questions
array and the
answers
array.
Figure 1.10
displays the object diagram of the
Quiz
application’s model objects.

 

Figure 1.10  Diagram of model objects in Quiz

 

Model objects typically use standard collection classes (
NSArray
,
NSDictionary
,
NSSet
) and standard value types (
NSString
,
NSDate
,
NSNumber
). But there can be custom classes, which typically have names that sound like data-bearing objects, such as
InsurancePolicy
or
PlayerHistory
.

 

View and model objects are the factory workers of an application – they focus tightly on specific tasks. For example, an instance of
UILabel
(a view object) knows how to display text in a given font within a given rectangle. An
NSString
instance (a model object) knows how to store a character string. But the label doesn’t know
what
text it should display, and the string doesn’t know
what
characters it should store.

 

This is where
controller objects
come in. Controllers are the managers in an application. They keep the view and model objects in sync, control the

flow

of the application, and save the model objects out to the filesystem (
Figure 1.11
). Controllers are the least reusable classes that you will write, and they tend to have names like
ScheduleController
and
ScoreViewController
.

 

Figure 1.11  MVC pattern

 

When you create a new iOS project from a template, the template automatically makes a controller object for you. For
Quiz
, this controller is the
QuizViewController
. Most applications have more than one controller object, but a simple application like
Quiz
only needs one. (Actually, the template creates another controller for
Quiz
– the
QuizAppDelegate
. Every iOS application has an

app delegate

object, and it is the primary controller of the application. However, to keep things simple, we won’t use the app delegate until
Chapter 6
.)

 

One of the
QuizViewController
’s tasks will be showing the user a new question when the
Show Question
button is tapped. Tapping this button will trigger a method in the
QuizViewController
. This method will retrieve a new question from an array of questions and place that question in the top label. These interactions are laid out in the object diagram for
Quiz
shown in
Figure 1.12
.

 

Figure 1.12  Object diagram for Quiz

 

This diagram is the big picture of
Quiz
. It’s okay if it doesn’t make perfect sense yet; it will make more by the end of the chapter.

 
Declarations

To manage its relationships and responsibilities, the
QuizViewController
object needs five instance variables and two methods. In this section, you will declare these in the
QuizViewController
header file,
QuizViewController.h
.

 
Declaring instance variables

Here are the five instance variables
QuizViewController
needs:

 

questions

a pointer to an
NSMutableArray
containing instances of
NSString

 
 

answers

a pointer to another
NSMutableArray
containing instances of
NSString

 
 

currentQuestionIndex

an
int
that holds the index of the current question in the
questions
array

 
 

questionField

a pointer to the
UILabel
object where the current question will be displayed

 
 

answerField

a pointer to the
UILabel
object where the current answer will be displayed

 
 

In the project navigator, select
QuizViewController.h
to open the file in the editor. Add the following code: a set of curly brackets and, inside the brackets, the declarations for the five instance variables. Notice the bold type? In this book, code that you need to add is always bold; the code that’s not bold is there to tell you where to type in the new stuff.

 
@interface QuizViewController : UIViewController
{
    int currentQuestionIndex;
    // The model objects
    NSMutableArray *questions;
    NSMutableArray *answers;
    // The view objects - don't worry about IBOutlet -
    // we'll talk about it shortly
    IBOutlet UILabel *questionField;
    IBOutlet UILabel *answerField;
}
@end

(Scary syntax? Feelings of dismay? Don’t panic – you will learn more about the Objective-C language in the next chapter. For now, just keep going.)

 
Declaring methods

Each of the buttons needs to trigger a method in the
QuizViewController
. A method is a lot like a function – a list of instructions to be executed. Declare two methods in
QuizViewController.h
. Add this code after the curly brackets and before the
@end
.

 
@interface QuizViewController : UIViewController
{
    int currentQuestionIndex;
    // The model objects
    NSMutableArray *questions;
    NSMutableArray *answers;
    // The view objects
    IBOutlet UILabel *questionField;
    IBOutlet UILabel *answerField;
}
- (IBAction)showQuestion:(id)sender;
- (IBAction)showAnswer:(id)sender;
@end

Save
QuizViewController.h
.

 

What do
IBOutlet
and
IBAction
do in the declarations you just entered? They allow you to connect your controller and your view objects in the XIB file.

 
Making Connections

A
connection
lets one object know where another object is in memory so that the two objects can work together. When the
Quiz
application loads
QuizViewController.xib
, the view objects that make up the interface and the
QuizViewController
have no idea how to reach each other. The
QuizViewController
needs to know where the labels are in memory so that it can tell them what to display. The buttons need to know where the
QuizViewController
is so that they can report when they are tapped. Your objects need
connections
.

 

Figure 1.13
shows the connections for
Quiz
. Some have already been made by the template (between the
view
outlet of
QuizViewController
and the
UIView
instance, for example), and some were made implicitly (dragging objects onto the view object in the XIB file set up connections between the view and the buttons and labels). However, you still have a few more connections to make to get your objects communicating properly.

 

Figure 1.13  Current connections and needed connections

 

Here are the missing connections:

 
  • QuizViewController
    , the controller object, must have pointers to the
    UILabel
    instances so it can tell them what to display.
 
  • The
    UIButton
    instances must have pointers to the
    QuizViewController
    so they can send messages to the controller when tapped.
 
Setting pointers

Let’s start with the connections to the
UILabel
instances. The instance of
QuizViewController
has a pointer called
questionField
. You want
questionField
to point to the instance of
UILabel
at the top of the view.

 

Select
QuizViewController.xib
in the project navigator to reopen it. In the outline view, find the
File's Owner
object (which is standing in for the
QuizViewController
). Right-click or Control-click on the
File's Owner
to bring up the connections panel (
Figure 1.14
). Then drag from the circle beside
questionField
to the
UILabel
.

 

Figure 1.14  Setting questionField

 
 

(If you do not see
questionField
here, double-check your
QuizViewController.h
file for typos. Did you end each line with a semicolon? Have you saved the file since you added
questionField
?)

 

Now when this XIB file is loaded when the application launches, the
QuizViewController
’s
questionField
pointer will automatically point to this instance of
UILabel
. This will allow the
QuizViewController
to talk to the label it calls
questionField
. This is the label on top of the screen.

 

Next, drag from the circle beside
answerField
to the other
UILabel
(
Figure 1.15
).

 

Figure 1.15  Setting answerField

 

Notice that you drag
from
the object with the pointer
to
the object that you want that pointer to point at. Also, notice that the pointers that appear in the connections panel are the ones that you decorated with
IBOutlet
in
QuizViewController.h
.

 
Setting targets and actions

When a
UIButton
is tapped, it sends a message to another object. The object that is sent the message is called the
target
. The message is called the
action
, and it is the name of the method that tapping the button should trigger. So the button needs answers to two questions:

Who’s the target?

and

What’s the action?

For the
Show Question
button, we want the target to be
QuizViewController
and the action to be
showQuestion:
.

 

To set an object’s target and action, you Control-drag
from
the object
to
its target. When you release the mouse, the target is set, and a pop-up menu appears that lets you choose the action. Select the
Show Question
button and Control-drag (or right-drag) to the
File's Owner
(
QuizViewController
). Once
File's Owner
is highlighted, release the mouse button and choose
showQuestion:
from the pop-up menu, as shown in
Figure 1.16
. Notice that the choices in this menu are the methods you decorated with
IBAction
in
QuizViewController.h
.

 

Figure 1.16  Setting Show Question target/action

 

Now set the target and action of the
Show Answer
button. Select the button and Control-drag
from
the button
to
the
File's Owner
. Then choose
showAnswer:
from the pop-up menu (
Figure 1.17
).

 

Figure 1.17  Setting Show Answer target/action

 
Summary of connections

There are now five connections between your
QuizViewController
and other objects. You’ve set the pointers
answerField
and
questionField
to point at the labels. That’s two. The
QuizViewController
is the target for both buttons. That’s four. The project’s template made one additional connection: the
view
outlet of
QuizViewController
is connected to the
View
object that represents the background of the application. That makes five.

 

You can check these connections in the
connections inspector
. Select the
File's Owner
in the outline view and then click the
icon in the inspector selector to reveal the connections inspector in the utilities area. (
Figure 1.18
).

 

Figure 1.18  Checking connections in the Inspector

 
 

Your XIB file is complete. The view objects have been created and configured, and all the necessary connections have been made to the controller object. Save your XIB file, and let’s move on to writing methods.

 

Other books

The Third-Class Genie by Robert Leeson
The Captains by W. E. B. Griffin
Mister Creecher by Chris Priestley
Small-Town Brides by Tronstad, Janet
Checkmate by Walter Dean Myers
Death in Cold Water by Patricia Skalka
A Spy By Nature by Charles Cumming