Hi Everyone,
Here goes, first tutorial, first iPhone app.
To make apps for iPhone you need to start by downloading Xcode, the apple provided programming tool. It is free, and if you have a relatively new version o
f OSX on your computer, you can even install
it from the CD instead. I'll leave that for you to figure out, there are instructions online somewhere if you get stuck.
Once you have it installed, it is time for your first app.
In keeping with programming tradition, I have to come up with some creative way to say "Hello World!" using an iPhone app.
Lets start with something simple. Open up Xcode, and choose File>New Project, pick iPhone OS Applications on the left, and pick View-based Application on the right.
Call this HelloWorld, and save it in a projects folder unless you really like a messy desktop.
Now we are presented with a stunning 13 files that are needed for this simple app.
Don't worry, most of them don't matter. Here are the ones I almost never touch:
- CoreGraphics.framework
- Foundation.framework
- HelloWorld-Info.plist
- HelloWorld.app
- HelloWorld_Prefix.pch
- main.m
- UIKit.framework
That leaves 5. the HelloWorldAppDelegate.h and .m files,
and the HelloWorldViewController .h, .m, and .xib files.
These groups of .h and .m files collectively represent a custom class. If you don't know what a class is, you may need a good book on Objective-C before we go too far with this, but you may not. Read on if you can learn very fast.
My favorite place to start is the .xib file, which is usually referred to as a nib file. I forget why that is. Double click on it and interface builder will pop open. If you don't see these 4 windows, you can get them from the Tools menu, (Inspector, Library) and window, (Bring all to front) and the one in the top center comes from double clicking on V
iew in the window at the bottom center.
Apple really did a good job with interface builder, you can play around with dragging things into and out of the window, they just drop in there and work. (Not that they do anything yet). Anything from the Inputs and Values group will at least sit where you put it, and if you save and close, (Command + S, Command + Q) then hit build and run in Xcode, they will be there in the window.
Let's start with a UILabel, and a UIButton.
Drag them onto the window, make the label say Hello World!, make the button say "Greet" or "Hello" or whatever you feel like, it doesn't really matter what it says. Here's mine:
Now save and close, (Command+S, Command+Q) and hit build and run.
If you have an iPhone or iPod plugged in, you may need to switch the top left picker from Device to Simulator.
There we have it, your first app.
No, not really, I was kidding, that isn't exciting at all. Now to make stuff work.
Now that we have these things in interface builder, the code needs to know about it somehow. That's where Actions and Outlets come from. Actions are really just functions, and Interface Builder tells your buttons and sliders to call them. Outlets are instance variables, and Interface builder assigns them when the nib loads.
So open up the HelloWorldViewController.h file. It should look remarkably empty and boring, something like this:
#import
@interface HelloWorldViewController : UIViewController {
}
@end
We want an instance variable to hold the label, so we can make changes to it. The normal way to declare an instance variable to hold a UILabel is to type in between the curly braces like below. We also want a method to be called so we can decide what to do when the button gets pressed. I used buttonPressed, with no return value (void) because a button doesn't need a return value.
#import
@interface HelloWorldViewController : UIViewController {
UILabel *helloLabel;
}
-(void)buttonPressed;
@end
We put a * in the declaration because the variable is a pointer to an object. This is fine if all we want is an empty pointer, but we want Interface Builder to connect it for us, so we put IBOutlet before that.
For the function, we tell Interface Builder about it with IBAction, and we put it in place of void.
Side Note: IBAction gets translated to void by the preprocessor when you hit compile. and IBOutlet gets translated to nothing.
#import
@interface HelloWorldViewController : UIViewController {
IBOutlet UILabel *helloLabel;
}
-(IBAction)buttonPressed;
@end
Now we can save this file and reopen the .xib file. In the main window (bottom center in my picture) click on File's Owner to select it. File's Owner is the Interface Builder representation of the HelloWorldViewController.h and .m files. With file's owner selected, click the Connections tab (blue arrow) in the Inspector window. You should see helloLabel under the Outlets section, and buttonPressed under received actions.
Next we want to connect these to the button and label. click on the little circle next to buttonPressed and drag over to the button. When you let go, a menu pops up with a lot of choices. We want touchUpInside, meaning they touched the button, and let go without sliding their finger off the button to cancel.
Next drag the helloLabel connection to the label. Once that is done, click on the label, and pick attributes on the inspector window (right) and slide the alpha to 0, making it transparent.
If you haven't guessed yet, I'm aiming to make the label appear when you touch the button. Now that the connections are set up, time for some coding. Save and close interface builder, and click the HelloWorldViewController.m. Here we need to implement the method we declared in the .h file.
@implementation HelloWorldViewController
-(IBAction)buttonPressed{
[UIView beginAnimations:@"showLabel" context:nil];
[helloLabel setAlpha: 1];
[UIView commitAnimations];
}
That's it. The first line is a repeat of the declaration, should be familiar if you know objective C. The next line is a class method to tell UIView not to make changes immediately, but animate them once we get to commit animations. since helloLabel is a UILabel, a subclass of UIView, it is able to check with UIView about when to make this change. Don't worry too much about how the animations work, they aren't the important part. The important part is making all these connections work together.
The setAlpha: command told the helloLabel to become visible.
If you build and run, this does what we want it to do, and makes the label visible.
Happy with that? I'm not yet, so here's an exercise to see if you understood:
Make the button also disappear when it is pressed, and make the Hello World move up to the center of the screen while it appears.
Hint:
helloLabel.center = self.view.center;
That's all for now, more soon.