You know how to make an interface, but how do you make it do
something? Throughout this hour, I’ve been alluding to the idea that
connecting an interface to the code you write is just a matter of
“connecting the dots.”
Launching Interface Builder from Xcode
To get started, we’ll use
the project Disconnected contained within this hour’s Projects folder.
Open the folder and double-click the Disconnected.xcodeproj file. This
will open the project in Xcode, as shown in Figure 1.
Almost all of your work in Interface Builder will start from inside of
Xcode, so we might as well get used to using it as our launching point
for IB.
Once the project is loaded,
expand the Resources file group and double-click the
DisconnectedViewController.xib file. This XIB file contains the view
that this application displays as its interface. After a few seconds,
IB will launch and display the interface Document window and the view,
as shown in Figure 2.
Implementation Overview
The interface contains four interactive elements: a button bar (called a segmented control),
a push button, an output label, and a web view (an integrated web
browser component). Together, these controls will interface with
application code to enable a user to pick a flower color, touch the Get
Flower button, and then display the chosen color in a text label along
with a matching flower photo fetched from the website http://www.floraphotographs.com. The final result is demonstrated in Figure 3.
Unfortunately, right now the
application does nothing. The interface isn’t connected to any
application code, so it is hardly more than a pretty picture. To make
it work, we’ll be creating connections to outlets and actions that have
been defined in Xcode.
Outlets and Actions
An outlet
is nothing more than a variable by which an object can be referenced.
For example, if you had created a field in Interface Builder intending
that it would be used to collect a user’s name, you might want to
create an outlet for it in your code called userName. Using this outlet, you could then access or change the contents of the field.
An action,
on the other hand, is a method within your code that is called when an
event takes place. Certain objects, such as buttons and switches, can
trigger actions when a user interacts with them through an event—such
as touching the screen. By defining actions in your code, Interface
Builder can make them available to the onscreen objects.
Joining an element in Interface Builder to an outlet or action creates what is generically termed a connection.
For the Disconnected app to function, we need to create connections to these outlets and actions:
ColorChoice: An outlet created for the button bar to access the color the user has selected
GetFlower: An action that retrieves a flower from the Web, displays it, and updates the label with the chosen color
ChosenColor: An outlet for the label that will be updated by getFlower to show the name of the chosen color
FlowerView: An outlet for the web view that will be updated by getFlower to show the image
Let’s make the connections now.
Creating Connections to Outlets
To create a connection
from an interface item to an outlet, Control-drag from the File’s Owner
icon either to the visual representation of the object in the view or
to its icon in the Document window of Interface Builder.
Try this with the button
bar (segmented control). Pressing Control, click and drag from the
File’s Owner icon in the Document window to either the onscreen image
of the bar or its icon in the Document window. A line will appear as
you drag, enabling you to easily point to the object that you want to
use for the connect. When you release the mouse button, the available
connections will be shown in a pop-up menu (see Figure 4).
By the Way
Interface Builder knows what
type of object is allowed to connect to a given outlet, so it will
display only the outlets appropriate for the connection you’re trying
to make.
Repeat this process for the label with the text Your Color, connecting it to the chosenColor outlet, and the web view, connecting to flowerView.
Connecting to Actions
Connecting to actions is a
bit different. An object’s events trigger actions (methods) in your
code. So, the connection direction reverses; you connect from the
object to the File’s Owner icon. Although it is possible to
Control-drag and create a connection in the same manner you did with
outlets, this isn’t recommended because you don’t get to specify which
event triggers it. Do users have to touch the button? Release their
finger from a button?
Actions can be triggered by many
different events, so you need to make sure that you’re picking exactly
the right one, instead of leaving it up to Interface Builder. To do
this, select the object that will be connecting to the action and open
the Connections Inspector by choosing Tools, Connections Inspector (or
by pressing Command+2).
The Connections Inspector, in Figure 5,
shows a list of the events that the object supports—in this case, a
button. Beside each event is an open circle. To connect an event to an
action in your code, click and drag from one of these circles to the
File’s Owner icon.
For example, to connect the Get Flower button to the getFlower
method, select the button, and then open the Connections Inspector
(Command+2). Drag from the circle beside the Touch Up Inside event to
the File’s Owner icon and release, as demonstrated in Figure 6. When prompted, choose the getFlower action.
After a connection has been made, the inspector will update to show the event and the action that it calls, as shown in Figure 7. If you click other objects, you’ll notice that the Connections Inspector shows connections to outlets and to actions.
Although most of your
connections in Interface Builder will be between objects and outlets
and actions you’ve defined in your code, certain objects actually
implement some built-in actions without you writing a single line of
code.
The web view, for example, implements actions, including goForward and goBack.
Using these actions, you could add basic navigation functionality to a
web view by dragging from a button’s Touch Up Inside event directly to
the web view object (rather than the File’s Owner). As described
previously, you’ll be prompted for the action to connect to, but this
time, it isn’t an action you had to code yourself!
|
Well done! You’ve just
linked an interface to the code that supports it. Switch to Xcode and
choose Build and Run to run and test the application in the iPhone
Simulator.
Object Identity
As we finish up our
introduction to Interface Builder, I’d be remiss if I didn’t introduce
one more feature: the Identity Inspector. You’ve already accessed this
tool to view the accessibility attributes for interface objects, but
there is another reason why we’ll need to use the inspector in the
future: setting class identities.
As you drag objects into
the interface, you’re creating instances of classes that already exist
(buttons, labels, and so on). Throughout this book, however, we’re
going to be building custom subclasses that we’ll also need to be able
to reference in Interface Builder. In these cases, we’ll need to help
Interface Builder out by identifying the subclass it should use.
For example, suppose we created a subclass of the standard button class (UIButton) that we named ourFancyButtonClass.
We might drag a button into Interface Builder to represent our fancy
button, but when the XIB file loads, it would just create the same old UIButton.
To fix the problem, we select
the button we’ve added to the view, open the Identity Inspector by
choosing Tools, Identity Inspector (Command+4), and then use the
drop-down menu/field to enter the class that we really want
instantiated at runtime (see Figure 8).