Wednesday, December 2, 2009

First iPhone Application - Tutorial II

Now, let's extend the previous one so that it responds to a button press!

1. Introduction
2. Add the button to the window
3. Connect button to action method
4. Build And Run
5. Analysis / Big Picture
6. Add Sound to the project

1. Introduction

Last time we had an app which showed an image and a label. It did not respond to any action button. This time, let's add an action button. We will add a button and when it is pressed, the label will show the text, and the app will also make a sound. So:
  • How to add a button to the interface builder ?
  • How to connect the clicking of that button to an action ?
  • How to play sound ?
Back to Top

2. Add the button to the window

- Double-click on the MainWindow.xib file. It should pop up the Interface builder as well.

- From the library, drag a "Rectangular Button" (of class UIButton) on to the window. You can play around with the attributes inspector to change its title. I gave the title "Wake him up!". I also erased the title of the other label we had earlier. We will show the text on the label when the button is pressed.


Back to Top

3. How to connect it to action?

This Button is just a user interface on the screen view. How to connect this to any action? It cannot control any data/action directly. The window cannot respond to the click of that button. That is where we need a Controller, that can knows how to respond to that click of the button. A controller is the connection between the data and the view. Since we are following the Interface Builder, we will create this controller object using that.

- Add a new controller file to the project. From XCode: File -> New File -> Cocoa Touch Class (under iPhone OS) -> Objective-C class (subclass of NSObject). Call it Controller. This will add Controller.h and Controller.m files to the project.



- Drag a "Object" from the library on to the MainWindow.xib. We gotta now connect the controller in the files to the controller in the MainWindow.xib. Click on the Controller object in the Mainwindow and in the Identity Inspector tab change the Class to "Controller".



- In XCode, add an IBOutlet and an IBAction method to the Controller class:

//  Controller.h  /////////////////////////////////
#import < Foundation/Foundation.h >
#import < UIKit/UIKit.h >

@interface Controller : NSObject {
IBOutlet UILabel *myLabel;
}

-(IBAction) onWakeUpButtonClicked:(id)sender ;

@property (nonatomic, retain) IBOutlet UILabel *myLabel;

@end
/////////////////////////////////////////////////


//  Controller.m


#import "Controller.h"


@implementation Controller

@synthesize myLabel;

- (IBAction) onWakeUpButtonClicked :(id)sender {
    myLabel.text = [NSString stringWithFormat:@"Dude, Wake up!"];
}

@end
////////////////////////////////////////////////////////

- The action method is supposed to happen when the button is pressed. The label should show the text that we want to show when the button is pressed. We have to connect this label and the action method to the ones on the Interface Builder.

- In IB, click on the Controller and in the Inspector, you should see myLabel under the Controller Connections tab. Draw a line from the small circle next to it to the label on the Window.



- In the window, click on the "Wake him Up" UILabel. In the connections, you should see a list of actions. Drag the circle next to "touch up inside" on to the "Controller" in the MainWindow.xib. In the little Menu that pops, choose "onWakeUpButtonClicked". Thus, we have established connections between the IB elements (which the user sees) to the code elements (which run the show behind the doors).



If you click on the Controller in the MainWindow.xib, you should see the onWakeUpButtonClicked method shown connected to the button in Received Actions (if you made the previous connection properly).


Back to Top

4. Build and Run..

You should see that when you press the "Wake Him Up" button, the label shows the text "Dude, Wake up!". We will also add the sound alert now. Before that, let's recap what we did so far in a big picture sense.

Back to Top

5. Analysis:


  • We had an image and a label on the window. We added a button to trigger some action when pressed. 
  • To be able to respond to the Button click, we had to make a controller object which knows how to respond to the button click. We instantiated the Controller object by dragging the block from library in to the MainWindow.xib. We connected that blob to the one in the code by defining it's "Class" in the Interface Builder (Step 3). 
  • We connected the action method to the button click via interface builder. We also had to make the label a member of the controller object, so that the text on that can be changed in response to the click. We connected the member myLabel of the Controller to one on the window. 
  • IBAction and IBOutlet are keywords that tell the Interface Builder to look for when we are making the connections. That is how when we click on the view, some action onWakeUpButtonClicked is triggered by the code. 

If you look at the Controller.m code, you will see that the onWakeUpButtonClicked method does nothing but sets the label's text to what we wanted.

- (IBAction) onWakeUpButtonClicked :(id)sender {
myLabel.text = [NSString stringWithFormat:@"Dude, Wake up!"];
}

Back to Top

6. Adding Sound to the Action Method:

It is very Simple indeed.

- Drag any sound file from the Finder to the "Resources" folder in left menu on XCode. (Mine is called danger.au . I found it somewhere in the Java Applets sound folder). A dialog box pops us asking you to add it to the PhotoFrame target.

- Add AudioToolBox to the Frameworks. Right Click on the FrameWorks folder, Add Existing Frameworks. Choose AudioToolbox. add "#import " in Controller.m

- Modify the onWakeUpButtonClicked method and use the AudioServices toolbox APIs to play the sound.


//  Controller.m
//  PhotoFrame
//
//  Created by Pannag Sanketi on 12/2/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "Controller.h"

#import < Audiotoolbox/Audioservices.h >


@implementation Controller

@synthesize myLabel;

- (IBAction) onWakeUpButtonClicked :(id)sender {
// Form a URL to the sound file, which in init using the Path
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:@"danger" ofType:@"au"];
NSURL *aFileURL = [NSURL fileURLWithPath:filePath isDirectory:NO];

// Create a sound ID,
SystemSoundID myID;
// Register the sound
AudioServicesCreateSystemSoundID((CFURLRef)aFileURL, &myID) ;
// Play the sound!
AudioServicesPlaySystemSound(myID);

// Put the label text to what we want
    myLabel.text = [NSString stringWithFormat:@"Dude, Wake up!"];
}
@end

Back to Top

7. Build and Run... with the sound!

There you go! When you press the "Wake Him Up" button, there is a sound played as well as the label shows the text "Dude, Wake up!".
Back to Top

1 comment:

  1. You can download the source code here:
    http://vehicle.me.berkeley.edu/~pannag/iPhone/PhotoFrame.zip

    ReplyDelete