Interface Builder is a visual design tool. It lets users create user interfaces for iPhone OS and Mac OS X applications. Using the graphical environment of Interface Builder, you assemble windows, views, controls, menus, and other elements from a library of configurable objects. You visually arrange these items, set their attributes, establish connections between them, and then save them in a special type of resource file, called a nib file. Interface Builder version 3, uses a new file format (with extension .xib). It is functionally identical to .nib, except it is stored in a flat file, making it more suitable for storage in revision control systems and processing by tools such as diff.
To build an interface, a developer simply drags interface objects from the palette onto a window or menu. Actions (messages) which the objects can emit are connected to targets in the application's code and outlets (pointers) declared in the application's code are connected to specific objects. In this way all initialization is done before runtime, both improving performance and streamlining the development process.
Interface Builder saves an application's interface as a bundle that contains the interface objects and relationships used in the application. These objects are archived (a process also known as serialization or marshalling in other contexts) into either an XML file or a NeXT-style property list file with a .nib extension. Upon running an application, the proper NIB objects are unarchived, connected into the binary of their owning application, and awakened. Unlike almost all other GUI designer systems which generate code to construct the UI (notable exceptions being Codegear's Delphi and C++ Builder, which stream UI objects similarly), NIBs are often referred to as freeze dried because they contain the archived objects themselves, ready to run.
for more information See the Interface Builder docs from Apple.
Interface Builder itself is not a coding environment; it is a visual design environment. Although you can use it to define new Objective-C classes, and to add outlets and actions to existing classes, the preferred approach is to use Xcode for those tasks. Interface Builder is tightly integrated with Xcode and is able to retrieve information about the classes in a project and make that information available to you as you work on the project’s associated nib files.
To make the most of Interface Builder’s integration with Xcode, you should do the following during development:
Keep your Xcode project open while editing your nib files.
Whenever you want to create a new class, or add an outlet or action to an existing class, do it in Xcode.
To set the class of an object, simply type its name in the Identity pane of the inspector window.
The Xcode integration works best if both Xcode and Interface builder are running at the same time. If your Xcode project is open, Interface Builder periodically queries it for information about new classes or changes to existing classes. You can tell if a document is associated with an Xcode project by looking at status bar along the bottom edge of the document window. This bar displays the name of the associated Xcode project and an indicator that lights up green when the project is available.
Note: Because it associates each nib file with a specific Xcode project, Interface Builder knows only about the classes that are defined in that project. If the project includes an external framework that defines custom controls or objects, you must add any class definitions from that framework to your nib file manually as described in “Establishing Connections to the First Responder.”
If Xcode is not running, Interface Builder supports alternate ways to associate your class information with your nib files. The following sections describe these techniques and show you how to use the Xcode integration to build your user interfaces efficiently. The Xcode integration is supported only for applications that use the AppKit or UIKit frameworks and is not supported for Carbon applications. For additional information about working in the Xcode environment, see Xcode Workspace Guide.
Setting the Class of an Object
Although most objects in the library are provided by the platform and have a known type, the library also contains generic objects (Figure 8-1) that you can use to represent any class in your project. Using these generic objects lets you incorporate custom code that is not otherwise part of the Interface Builder library. Placeholder objects, like File’s Owner, are another type of generic object whose class you must set prior to use.
Figure 8-1 Generic objects
To add a custom view or object to your Interface Builder document, do the following:
Drag the desired object from the library.
For a generic view, drop it onto your window’s design surface. (You can also drop views onto the Interface Builder document window if you just want a view resource without a surrounding window.)
For a generic object, drop it into your Interface Builder document window.
Select the view or object.
Open the identity inspector.
Use the available controls to configure the class information.
In Cocoa and Cocoa Touch nib files, configure the class name using the Class Identity section of the identity inspector; see Figure 8-2. Type the name of your class in the Class field or use the combo box control to select the class from the current list of known classes.
Figure 8-2 Setting the class of an object
In Carbon nib files, specify the Class ID of the class in the Class Identity section of the identity inspector.
If your nib file is associated with an Xcode project, Interface Builder attempts to complete the class name automatically as you type it. When the class is set, Interface Builder displays the known outlets and actions for that class in the inspector. If your nib file is not associated with an Xcode project, Interface Builder displays the class name but does not display any outlets or actions initially. You can add outlet and action information using the appropriate sections of the inspector if you like. If you do so, however, you must manually add those same outlets and actions to your source files later. For information about using Interface Builder to define outlets and actions, see “Defining Outlets and Actions in Interface Builder.”
Because the Classes library makes it easy to instantiate your custom classes, the recommended workflow is:
Create your custom classes in Xcode.
Instantiate them in Interface Builder by dragging them out of the Classes library.
This eliminates the need to drag out a generic view or object and then set its custom class.
Defining Outlets and Actions in Xcode
In Cocoa and Cocoa Touch applications, outlets and actions are a way to create dedicated connections among the objects that exist both inside and outside of a nib file. Outlets are essentially instance variables that refer to other objects. Actions are messages that objects send to an associated target object in response to certain events. You identify outlets and actions in your code using the
IBAction keywords as described in the following sections.
Note: Carbon applications do not support the use of outlets and actions. Instead, Carbon objects must be configured with command IDs that are then used by the underlying code to respond to interactions with views and controls. For more information on configuring Carbon nib files, see “Specifying Carbon Attributes.”
To add an outlet to your class, insert the
IBOutlet keyword in front of one of its instance variable or property definitions, as shown in the following example:
@interface MyClass : NSObject
IBOutlet id aGenericOutlet;
IBOutlet NSView* aViewOutlet;
// Objective-C 2.0 only.
@property IBOutlet id aPropertyOutlet;
@property(retain) IBOutlet id aRetainedPropertyOutlet;
Outlets can be weakly typed or strongly typed in your code. Weakly typed outlets (those whose type is
id) can be connected to any object in your nib file. Strongly typed outlets can be connected only to an object whose class matches the type of the outlet. When exposing a property as an outlet, the
IBOutlet keyword goes immediately before the property’s type information and after any parenthetical attributes. For more information about properties and Objective-C 2.0, see The Objective-C Programming Language.
Note: The initialization methods for your class should set the value of any outlets to
nil. The nib-loading code reconnects outlets only after the objects in the nib file have been created and initialized. For more information on the nib-loading process, see Resource Programming Guide.
Defining Action Methods
An action message sent by an object to its target results in the invocation of an action method on the target object. In essence, this is just another way of saying that the object that sends an action message does so simply by calling a method of its target object. Therefore, in order to define an action, you actually define an action method on the corresponding target object. The definition of this method is where you respond to the action. For example, if the user clicks or taps a button, the corresponding action method is where you would write the code to respond to the button interaction.
In Cocoa applications, an action method takes a single parameter of type
id and returns the type
IBAction, which is defined as
void. The name of the action method can be anything you want but is typically evocative of the action being performed. For example, to respond to a click in a button, you might define the following method in the controller object that manages the button:
In Cocoa Touch applications, an action method can take one of three forms, shown here:
- (IBAction)respondToButtonClick:(id)sender forEvent:(UIEvent*)event;
Action methods do not require a one-to-one correspondence with the controls in your interface. You can define one action method for each control in your interface or several controls can share a single action method. When present, the sender parameter in an action method contains the object that sent the action and can be used to help process the action. In iPhone OS, the optional event parameter conveys additional details about the specific type of event that triggered the action.
If you subclass standard system classes, you should check the definitions for any parent class before adding your own custom action methods. For example, many Cocoa classes already implement
paste: action methods to respond to pasteboard actions. Using inherited action methods lets you respond to messages sent by your own code and also messages sent by the system. In general, you should implement custom action methods only when the action methods provided by parent classes are insufficient or do not provide the behavior you need.
Synchronizing With Your Xcode Project
If your Interface Builder document is already associated with an Xcode project, you do not have to do anything to synchronize the two. When you change your source files in Xcode and save those changes to disk, Interface Builder automatically detects those changes and updates its internal copy of the information. In other words, if you add an outlet to a custom view in Xcode and then switch to Interface Builder, that outlet will appear automatically in the connections panel and inspector windows for that view. Of course, the Xcode syncing support is contingent upon the ability to parse your code successfully. If your code contains syntax errors, Interface Builder may not be able to read the changes.
If you disable the automatic syncing option in the Interface Builder preferences, you can sync your Xcode project manually by choosing File > Reload All Class Files. This command forces Interface Builder to reread any source files containing relevant class definitions.
Creating Classes in Interface Builder
Although Xcode is the preferred environment for creating new classes, there may be cases where you want to define your nib file first, including the definitions for any custom classes. The following sections show you how to do this in Interface Builder.
Defining New Classes in Interface Builder
The ability to reference unknown classes in Interface Builder lets you rapidly prototype your user interface without worrying about the underlying code. You can change the class name and change the names of outlets and actions as needed. Once you are satisfied with your prototype, you can generate source files for any unknown classes from Interface Builder and begin writing the code for those classes. After generating the source files, you can also specify the superclass for your class. For information about generating class files, see “Generating Source Files for New Classes.”
Interface Builder 3.2
In Interface Builder 3.2 and later, to define a new Objective-C class do the following:
In the Library window, click the classes tab and select the class you want to subclass.
From the action menu, choose New Subclass.
Enter the name of the subclass and whether or not to immediately generate source code files.
If you plan to add outlets and actions to the subclass, wait and generate the source code files later.
Click OK (or press Return) to define the new class.
Interface Builder 3.1 and Earlier
In Interface Builder versions earlier than 3.2, to define a new Objective-C class do the following:
Select the object whose class you want to set.
Open the inspector window and select the Identity pane.
In the Class field, type the full name of the class.
Press Return (or select another field) to apply the class name.
When you type the name of an unknown class in the identity inspector, Interface Builder assumes that this class exists somewhere outside the nib file. After creating the class, you can define outlets and actions for it as described in “Defining Outlets and Actions in Interface Builder” and use those outlets and actions to create connections in your nib file. Classes created in this manner have an unknown superclass and exist only within Interface Builder.
Defining Outlets and Actions in Interface Builder
When present, the Class Outlets and Class Actions sections of the Library window display the known outlets and actions of the currently selected class. In addition to viewing the existing list of outlets and actions, you can also add new ones using the controls found in these sections. You would typically use this feature during prototyping, when your nib file does not yet have an associated Xcode project. For example, you might create a new class for your prototype and add outlets and actions to get a sense of what behaviors you would need in your code.
Note: Beginning in Interface Builder 3.2, the management of actions and outlets and been moved from the identity inspector to the classes tab in the Library window. The only exception to this is the First Responder. Actions and Outlets for the First Responder have been moved to the attributes inspector.
Figure 8-3 Defining outlets and actions in the Library window
To add an outlet or action, do the following:
Click the plus (
+) button in the appropriate section to add the new action or outlet.
Type a new name.
As you type the name of an action method, Interface Builder displays warnings in the Class Actions section of the inspector to let you know if you are specifying an invalid method name.
In Mac OS X, action methods take a single parameter and therefore the method name must end with a colon (“:”) character.
In iPhone OS, action methods may take zero, one, or two parameters.
Optionally, specify a custom type for outlets by typing the appropriate class name. (You can also change the parameter type of action methods, although
idis the standard parameter type.)
To remove a custom defined outlet or action, select it in the identity inspector and click the minus (
-) button. You can remove only those outlets and actions you previously added using Interface Builder. You cannot remove outlets and actions you created in your Xcode source files or those defined in a Cocoa parent class.
The outlets and actions you add using the Library window remain local to Interface Builder and your Interface Builder document. Interface Builder does not attempt to merge these outlets and actions back into your Xcode source files; you must do that manually. You can write out source and header files containing the outlet and action definitions for your class by choosing File > Write Class Files. You can then use the generated files as your initial source or merge their contents in with your existing source files using your favorite merge tool, such as the FileMerge application.
Note: To copy outlets and actions into your Xcode source files, you can drag entries from the Library window and drop them into the corresponding source file. Xcode pastes a properly formatted outlet or action declaration into the source file at the drop point. You can also select an outlet or action entry in the Library window and select Edit > Copy to copy the declaration to the pasteboard.
Generating Source Files for New Classes
If you create new classes using the Library window, you can ask Interface Builder to create an initial set of source files for those classes. When generating source files, Interface Builder also generates the appropriate set of member variables and methods corresponding to the outlets and actions of the class. This feature helps your prototyping efforts by eliminating the need to recreate your class definitions manually in Xcode.
To generate source files for a class you defined in Interface Builder:
Select the object that uses the desired class.
Choose File > Write Class Files.
Interface Builder prompts you to save the new source files.
Open the header file.
Specify the superclass information for the class.
Beginning in Interface Builder 3.2, you can generate or update source files using the classes tab in the Library window:
Select the class for which you want to generate or update source files.
Display the action menu and choose Write Updated Class Files or Generate Class Files.
After generating the source files, you should add them to your Xcode project and make any future changes from there. Changes made to source files in your Xcode project are automatically picked up by Interface Builder, but the reverse is not true. Interface Builder does not update source files after it generates them. Instead, you must incorporate any additional changes into the source files manually from Xcode.
Injecting Class Information into a Nib File
As much as possible, Interface Builder relies on Xcode to provide it with information about your project’s custom classes. If you are writing a Cocoa or Cocoa Touch application and that information is not available, however, you can provide it manually by doing one of the following:
Drag the class header files from Xcode or the Finder and drop them onto your Interface Builder document window.
From Interface Builder, choose File > Read Class Files and select the header files.
When you use either of these techniques, Interface Builder parses the provided header files for information and caches that information in your Interface Builder document. The cached information remains valid until the next time you import header files or until Interface Builder accesses the class information from the associated Xcode project.
If the header files you import refer to other custom classes, you should import the header files for those other classes as well. This is especially important if the parent of your custom class is also a custom class. Without the full parent class hierarchy, Interface Builder cannot build a complete picture of the outlets and actions of the class. However, you do not need to import classes defined in the AppKit or UIKit frameworks or those that are defined in an Interface Builder plug-in.
Scripting Language Support
You can use Interface Builder for more than just Cocoa, Carbon, and iPhone applications. Interface Builder also provides support for applications built using the Ruby, Python, and AppleScript scripting languages and can parse script files that contain the appropriate keywords.
If you are a Ruby, Python, or AppleScript developer, you can take advantage of the Cocoa scripting bridge to write your application code and use nib files to create your application’s user interface. As you build your interface, you associate elements from that interface with objects in your scripts much like you would associate them with Objective-C objects. For information about how to use the Cocoa scripting bridge, including the keywords you need to add to your script, see Scripting Bridge Programming Guide for Cocoa and Ruby and Python Programming Topics for Mac OS X.