Friday, December 18, 2009

Simple Ball Animation

It has been a while since I last wrote any tutorial, so here is one more. This tutorial is inspired by a noobie's post in the iphonedevsdk.com forum. I know how hard it can be to start learning to code in XCode, especially if you are new to Obj-C and also new to Mac (like I was 2 months ago). Most of tutorials that exist in the web few months ago (that I could google anyway), are mostly too simple, like a Hello World app. That just not good enough. Sometimes, a bit more variety of the Hello World app could help much more to noobies, right? So that is why I created this tutorial blog - to help noobies get further from just displaying Hello World in their app. =p




Enough ramblings, lets get started. Here is how the app will look like. Immediately upon startup, you will see a small ball moving around randomly.


Let's plan our code according to what we want to do with the app.

1. We want a ball - so we need a UIImageView AND a ball image.
2. We want it to move around  - so we need to figure out how the ball is going to move, and to which location. This will involve a little Maths.

First, lets declare the ball in the header file:


 UIImageView *myball; // ball declaration
...
@property (nonatomic, retain) IBOutlet UIImageView *myball; // ball declaration


Secondly, let's declare a method to move the ball.


 -(void)movetheball;


Now we have these two things set up, we can now able to reference the ball so that we can change its coordinate, via the method.

Before we go on to write the code in the main file (.m file), it is better we connect the ball (ie, myball) to the corresponding UIImageView in Interface Builder. Im assuming you already know how to do that, so just connect it to the File's Owner and you select the myball label appeared in the list.

Once it is connected, you can add a ball image to your resource folder. This image can be any name, but preferably of type PNG. Adding the image to your project is very easy - you just drag the image from Finder into the XCode left pane under "Resources" folder. A confirmation box will pop up and you just click Add. Once you added the image to your project, you need to display it in the UIImageView that you just placed in IB. So, in IB, select the UIImageView and goto the first tab (with a slider icon on it), and select your image from the drop down list of Image. That's all for setting up the interface side!

Now, we come to writing the code. Open up .m file of the project, and synthesize the ball, by typing:

 @synthesize myball;


Then, we need a global variable to store the coordinates of the ball, as follows (put this under @synthesize is good).

 int ballx, bally;


Note: Something about the iPhone screen/display: In portrait mode, its size is 320pixel wide and 480pixel high. A coordinate of 0,0 is at the top left hand corner (origin).

Now, in this app, we will make the ball start moving immediately after the app is loaded, so we make use the viewdidload method. Write the code as below:


 // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
 
 ballx = arc4random() % 320; // this will create a random number from 0-320
 bally = arc4random() % 480; // this will create a random number from 0-480
        [self movetheball];
 [super viewDidLoad];
}


What the code above is doing is:
1. set x-coordinate to be a random position between 0 and 319 horizontally.
2. set y-coordinate to be a random position between 0 and 479 vertically.
3. call the movetheball method (custom method that we need to write).

Next, lets write the movetheball custom method. This method needs to do:
1. Take the UIImageView myball,
2. do animation movement on it within 1 second period.

I comment the method's code for the description.

 -(void)movetheball {
        // tell the app we are making animation. The name MovingTheBallAround is arbitrary.
 [UIView beginAnimations: @"MovingTheBallAround" context: nil]; 
        // set the delegate to self - otherwise the delegate method wont be called!
 [UIView setAnimationDelegate: self]; 
        // this line set the animation length in seconds.
 [UIView setAnimationDuration: 1.0];
        // this line specify the type of animation. EaseInOut, EaseIn, EaseOut and Linear are the options.
        // try to change it and see the effect.
 [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
 
        // just before calling commitAnimations below, you write the code to make the changes of the
        // imageview and XCode will do the rest. It is that simple.
        // In this case, we are setting coordinates of the image to ballx and bally.
 myball.frame =  CGRectMake(ballx, bally,myball.frame.size.width,myball.frame.size.height);
 
 [UIView commitAnimations]; 
}

Next, since we want the ball to move forever, we need to move the ball again after it has finished the movement/translation. So, how do we know when the ball has finished moving? Here comes the animationdidStop DELEGATE method. Delegate method is something like a public method for a certain actions - in this case for the animation action. Whenever any animation stop, this method will be called. All you need to do is handle the messages the app sent to it.

So in the delegate method, we need to re-set the ball coordinate to another random value and then, call the movetheball method again to animate it to a new position.


 - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(SEL)aSelector {
 if (finished) {
  // set new coordinate for ballx and bally
  ballx = arc4random() % 320; // this will create a random number from 0-320
  bally = arc4random() % 480; // this will create a random number from 0-480
   // then recall the move ball method
  [self movetheball];
 }
}

Do note that delegate methods' name are pretty much fixed. You must write the name as it is, in this case animationDidStop. Do not spell it wrongly (which is a common mistake among new coders).

Play around with the values and see what happens.


Friday, November 20, 2009

A Simple About Box

Hi fellas. I've been wanting to write 2nd tutorial for sometime, but really is pushing my own schedule to submit my 3rd app. Anyways, those who stopped by, do notice that this is a tutorial blog for Noobies. Like me. If you are looking for advanced stuffs, I'm not there yet. Perhaps sometime in the future, xcodeadvanced.blogspot.com would be born. =p


Anyways, getting back to main subject: Today's tutorial is to create a simple About Box that displays your information - such as website URL, version of the app, your name, and a logo of your company. Below is how it will look like:



Before I go on with this tutorial, I do realize that some dev likes to use a full page of UIView to display as About Box and put all fancy backgrounds etc. For me, I don't like to waste resources so much in stuffs that are not benefiting the users. So I make full use of the UIAlertView class.

Lets start:

First, I create a new project -> A Single-View Template. (I love Single View!) In this project, I gave it a name of ImageInAlert.proj.

Next, we declare an IBAction method/function in the ImageInAlertViewController.h (header file).

 -(IBAction)showAboutBox;

We do not need to know who is calling the method, so the (id)sender extension parameter is omitted. Once this is done, SAVE IT, and then open the ImageInAlertViewController.xib. Put a UIButton on it. Put a title on the UIButton, mine says "About".

Now, select the UIButton and go to Connections window and select the second tab (with a picture of an arrow pointing to the right on it) Under "Events" section, connect the "Touch Up Inside" to the File's Owner icon in the Main xib window. You need to move around your View if you can't see the Main xib window.

You should see a list pop up, select showAboutBox. And now the button is connected to our method/function. SAVE THE XIB FILE.

*Make it a habit to save every now and then.. because if you don't save, what you have typed in or changed, will not be updated in XCode, therefore can't be detected in IB, and vice versa.*

Now go back to the Main file: ImageInAlertViewController.m. Type the following code:


 -(IBAction)showAboutBox {
// Part 1
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"AlertView Tutorial"
message:@"\n"
@"\n"
@"\n" // Part 2
@"\n"
@"\n"
@"Created by: \n"
@"Emir F Samsuddin \n"
@"http://xcodenoobie.blogspot.com"
delegate:nil
cancelButtonTitle:@"Ok" // Part 3
otherButtonTitles:nil];
// Part 4
UIImageView *iemirlogo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"MainIcon.png"]];
iemirlogo.contentMode = UIViewContentModeScaleToFill; // Part 5
iemirlogo.frame = CGRectMake(90, 40, 100, 120); // Part 6
[alert addSubview:iemirlogo]; // Part 7
[iemirlogo release]; // Part 8

[alert show]; // Part 9
[alert release]; // Part 10

}

Ok, Im going to explain part by part: Refer to the above label while reading below:

Part 1: Declare a name for the UIAlertView object that we are going to create. I give it a name of alert.

Part 2: All the /n are so that it skip a line. Its like pressing the Enter/Return button on your Mac. I do this so that I can have a space to put my image there later on.

Part 3: Cancelbuttontitle is the title for the cancel button (ie the button that when user pressed, will dismiss the about box)

Part 4: Here is the fancy part (well for a noobie anyways), we create an imageview object, and directly load an image from project resources into it. "MainIcon.png" is already been dragged into the Resources folder. This is the image that I will make appear at the alert view.

Part 5: Set the image property so that the image is scaled following the size of the UIImageView frame. The property name is contentMode and the value is UIViewContentModeScaleToFill

Part 6: Define the size and location of the image in the form of CGRectMake(x,y,width,height). x and y is the location of the image, measuring from the top left hand corner of the image. width and height, er.. are the Width and Height of the image frame. Try experimenting with these values to get what you finally want.

Part 7: Finally, we add the image to the AlertView. addSubview is a useful method to add anything to anything.

Part 8: We have added the image to the AlertView, so we clear/release the image from memory.

Part 9: Show the alert box. (ie, make it pop out)

Part 10: We have shown the alert to the main view, so we clear/release the alert from memory.



Tuesday, November 10, 2009

Creating Flashing Custom Button



If you used UIButton before, you will know that there are 2 iPhone built-in info buttons, which functions to go to Settings view of an app. They are those circular button with an "i" at the center of it.
If you tap on it, it will flash and the effect is pretty nice.


Now, I wanted to use this button for my app because of its flashing effect, but not for the settings purpose. So I decided to make my own flashing button. (Do note that if you use the built in info button for other purposes, your app MAY BE REJECTED, because it is not what Apple intended them to be).

Anyway, back to the main subject: Creating a flashing button. 

1. First you need to create your own button image. I used the GIMP program which ran off X11 terminal in my Mac. I love GIMP. Because its function is a lot similar like Paint Shop Pro/ PhotoShop program in my Windows box. All the tools are so familiar.

2. Once you created the button image, save it as PNG and set the background of that image as transparent - you need to know your graphics program to do this.

3. Next, create another image that resembles a white flash (or whatever color u wish). You can use the radial gradient tool to accomplish this. Make sure the background of the image is transparent too.

4. Once you have both image ready, then you can load it up in the "Resources" of your XCode project. (Just drag and drop under the Resources folder in the XCode).

5. Next, declare the white flash image in header file, this case, its the FlashingButtonViewController.h.

 
IBOutlet UIImageView *flashimage;

and also the related declaration as @property.

6. Go to FlashingButtonViewController.m main file, and add to synthesize:

 
@synthesize flashimage;

7. After that, declare the function that is going to be called when user tap the button. So we declare in FlashingButtonViewController.h:-

 
-(IBAction)custombtnclicked:(id)sender;

8. Then return back to Main file and write the function for custombtnclicked:-

 
-(IBAction)custombtnclicked:(id)sender {

[self flashit:flashimage];

}

[self flashit:flashimage]; is just a way to call another function from this function. I do it this way so that, if you have many other buttons you want to behave this way, then you don't need to rewrite a long function. So the function to flash the flashimage is:

 

-(void)flashit:(id)sender {
UIImageView *img = (UIImageView*)sender;
img.alpha = 0.8;
[UIImageView beginAnimations: @"FadeOut" context: nil];
[UIImageView setAnimationDelegate: self];
[UIImageView setAnimationDuration: 0.5];
[UIImageView setAnimationCurve: UIViewAnimationCurveEaseInOut];
img.alpha = img.alpha - 0.8;
[UIImageView commitAnimations];
}


What this function does is: declare the "sender" parameter as an imageview. Then set its alpha to 0.8 (1 is fully opaque, and 0 is invisible). Then we start to create animation of UIImageView.
We set the duration to 0.5seconds for the whole of animation of flashing. And the type is Curve Ease In and Out.This means the animation will start slowly, then fast, then back to slow before stopping.

Next, we tell XCode what to do with the image. This just return back the alpha channel back to 0 (invisible).

Basically, when user taps the button, we set the flashimage to fully opaque, then animate the fading out of the flashimage for 0.5seconds. Finally we tell XCode to execute the animation by calling commitAnimations. XCode will do the rest.

9. Now that you have all the codes ready, its left only to open up FlashingButtonViewController.xib in Interface Builder and place the buttons in and images in. But remember to place the flash image BEHIND the button, so that user can touch the button. You can use the Layout menu of XCode and selecting "Send to Back" function to send the flashimage to the back of the button. Finally, set the alpha of the UIImageView to 0, so that it is invisible.

10. Once all user interface items are created, it is time to link them to XCode variable declaration. Connect the "Touch Up Inside" of the UIButton to the function called customButtonclicked: and set the Outlet of the flash image to "flashimage".

11. Save all files and everything. Then it should be able to run and when you click the button in the simulator, it will flash and fade away.

Thats all.