Per Ola Kristensson | Blog

Blog
Publications
Software
Other Stuff

Archive for the ‘objective-c’ Category

Connecting iPhone UI widgets designed in Interface Builder to Objective-C code in Xcode

Monday, December 6th, 2010

When I design an iPhone app I tend to use Interface Builder. However, I always forget how to actually connect the widgets (buttons, labels and so on) in Interface Builder to variables I can reference in my Objective-C code in Xcode. Hence this post. Note that this is one approach, there are several others. However, the procedure I describe below is beneficial as it is quite simple, yet usually all that is required.

Step 1. Design some widgets using Interface Builder

The way I usually do it is to simply start a new project, open the Resources tab in the Groups & Files sidebar, and then double-click on a pre-generated Interface Builder XIB file (for example, MainView.xib).

(Note: The screen captures and code fragments I will show below are from a simple project that was automatically generated from the Utility Application code template provided by Apple. A Utility Application project has two default views: a MainView and a FlipsideView. The procedure I describe works for any iPhone application, so if you don’t understand references to FlipsideView and other objects then just ignore them for now.)

Then I design some rudimentary user interface, like this one (click for a larger image):

Step 2. Create outlets in your code

OK. So we have designed a user interface using Interface Builder. Now, how do we access all these widgets in our code? Here I will describe how we are going to connect the button labeled Next in the above screen capture to a variable named nextBtn.

First, declare the instance variable nextBtn in your interface (for example, MainViewController.h):


@interface MainViewController : UIViewController <FlipsideViewControllerDelegate> {
    UIButton *nextBtn;
}

Below your interface declaration, introduce an outlet that references the instance variable you declared above:


@interface MainViewController : UIViewController <FlipsideViewControllerDelegate> {
    UIButton *nextBtn;
}
 
@property (nonatomic, retain) IBOutlet UIButton* nextBtn;

You have now declared that your class contains a UIButton instance, and this instance variable can be accessed via an IBOutlet. However, no code has been generated to set the value of this variable yet. To do so, open up the corresponding implementation file (for example, MainViewController.m) and introduce the following line somewhere below the @implementation declaration:


@synthesize nextBtn;

Step 3. Connect Interface Builder widgets to your outlets in Xcode

Now that we have created the necessary instance variables and outlets we can open up Interface Builder and connect the widgets to the corresponding variable declarations in the code. First, select File's Owner in Interface Builder’s Inspector window:

Then open the Connections Inspector (Command-2). In the Outlets section you will see a small connector (circle) to the right of a label named nextBtn. If you hover over the connector it will highlight and turn into a plus-sign. Click it and drag the blue thick line that appears to the button in the interface you wish to connect to nextBtn. See below for an illustration (click to enlarge):

Step 4. Create actions for your Interface Builder widgets

The next step is to implement a method that will be called when an action is triggered for the button. To do this we first add the following function prototype to the header file (for example, MainViewController.h):


- (IBAction)respondToButtonClick:(id)sender;

Thereafter we add a function body to the implementation file (for example, MainViewController.m):


- (IBAction)respondToButtonClick:(id)sender {
    NSLog(@"The user clicked on the nextBtn button!");
}

The code above prints out a message to the console whenever the button labeled Next is pressed by the user (to view the console press Shift-Command-R).

Step 5. Connect Interface Builder widget actions to your designated methods in Xcode

Now we need to tell Interface Builder which function it should call when nextBtn is pressed. Open up Interface Builder again and click on the button in the user interface which we previously connected to the nextBtn variable. The Connections Inspector will change and show you a list of possible actions this button can take. Now click on the connector (circle) for the action Touch Up Inside and drag it to File's Owner in the Inspector (click for a larger image):

A menu will pop up and propose possible methods in your code that could receive the action:

Choose respondToButtonClick:. Then save your interface design in Interface Builder.

All done!

Now we can run the program on an iPhone or via the emulator. Whenever you press the button labeled Next a message appears in the console (click to enlarge):

Voila! You can now access the button labeled Next using the nextBtn instance variable in your code. Further, whenever a user presses this button, your method respondToButtonClick: will be invoked and execute any custom code you insert here.

The above procedure used a single button for illustration purposes. However, this procedure generalizes to all widgets and actions supported by Interface Builder. Have fun!

For more information, check out Apple’s own documentation on integrating Interface Builder with Xcode.

Using Objective-C to teach object-oriented programming?

Monday, September 6th, 2010

I am programming in Objective-C right now. It is an interesting programming language, essentially a smaller and simpler alternative to C++. However, unlike C++, Objective-C is a strict superset of ANSI C, which means any valid C code can be compiled by an Objective-C compiler, something that a C++ compiler cannot guarantee (for instance, the need to cast void-pointers is different in C and C++).

What Objective-C does is add additional well-needed abstractions to ANSI C, such as classes, interfaces and inheritance. I have to admit, coming from mostly C and Java programming, I was initially annoyed by the Smalltalk-inspired syntax (and I’m still not convinced it makes any sense).

However, I am starting to think that Objective-C might be a good teaching language for an ambitious programming class. Unlike Java and C++, Objective-C’s syntax clearly differentiates between standard function calls and instance method invocations (message expressions). The syntax also differentiates between method declarations and function declarations.

The theory is that by having distinct syntax for these and other aspects of the programming language the learner is forced to conceptualize the differences. Syntax is enforced by the compiler and conceptual misunderstandings will lead to compilation errors that the learner has to correct. In other words, conceptual misunderstandings are explicitly pointed out to the learner by the compiler. If the learner does not satisfy the compiler the program won’t compile, let alone run. For example, the Objective-C syntax makes it impossible to call an instance method and not realize that this is message passing and not a static function invocation.

Another potential advantage of using Objective-C as a teaching language is that it is somewhere in the middle between Java and C++. It is closer to the hardware than Java. For instance, when an object is created in Objective-C, the idiom is to first explicitly allocate memory for it and thereafter initialize it (e.g. the expression UIButton *button = [[UIButton alloc] init]; first allocates memory for a structure to represent the button, and then initializes it). This first step of allocation and memory management is hidden for Java programmers. However, computer science students obviously need to understand memory management. Yet Objective-C is not as convoluted as C++. For instance, it doesn’t have operator overloading, templates and multiple inheritance. Hence it is not too daunting for the beginning programmer.

This tutorial succinctly highlights the differences between Objective C and C.