iPhone SDK Example: Moving And Rotating Image Part 1
May 1, 2009

There are what will be demonstrated:

* Using Transformation.
* Using UIImageView.
* Using interval for animation.
* Associating image with objects.
* Deriving a class from UIImageView.

Step 1

Create a New Project. Select iPhone OS Application -> View-Based Application. Name it Ball.

Step 2

Import an image into the Resources Group.  If you use transparent png, the transparency will be intact.  I am using a smiley-face image that I downloaded from: http://noobr.net/2009/02/15-smiley-icon-sets-express-yourself/

Your project window should now look like this:


The easiest way to load an image is to use UIImageView class.  We can either load the image by adding a UIImageView in the Interface Builder; or you can load the image by manually creating an UIImageView and attaching the image to it.  We are going to do both, just for demonstration purpose.  First, let’s use the first method, which is to load the image from Interface Builder.

Step 3

Derive a class from UIImageView.  Why use a derivation instead of just UIImageView?  Because we are adding some extra properties to the view, such as speed and rotation.  Create a File->New File.  Select Cocoa Touches Classes.  Name it Ball.m.  We are going to derive Ball from UIImageView, so edit Ball.h and enter this:

#import <Foundation/Foundation.h>

@interface Ball : UIImageView {
    int mXSpeed;
    int mYSpeed;
    float mAngle;
- (void)move;
- (void)setSpeedX:(int)xSpeed Y:(int)ySpeed;


The 3 new variables will be used to animate the image.

Step 4

Add the following into Ball.m.  The setSpeed funtion is used to set the speed of the Ball.  The move function will be called by a timer to animate the ball.  We are also checking for boundaries and reversing the speed when the ball hits the screen edges.  Then we rotate the image using CGAffineTransformMakeRotation.

#import "Ball.h"

@implementation Ball

- (void)setSpeedX:(int)xSpeed Y:(int)ySpeed {

- (void)move {
    self.center=CGPointMake(self.center.x + mXSpeed, self.center.y + mYSpeed);
    if (!CGRectContainsRect(self.superview.frame, self.frame))
        if (self.frame.origin.x<self.superview.frame.origin.x)           
        if (self.frame.origin.x>self.superview.frame.size.width-self.frame.size.width)           
        if (self.frame.origin.y<0)//self.superview.frame.origin.y)           
        if (self.frame.origin.y>self.superview.frame.size.height-self.frame.size.height)           
    self.transform=CGAffineTransformMakeRotation (mAngle);

superview is the parent of the current view, it is a member of UIView.

Step 5

We need create an instance of Ball in the main view object, which is BallViewController.h.  Open it and add:

#import <UIKit/UIKit.h>

@class Ball;

@interface BallViewController : UIViewController {
    IBOutlet    Ball* mBall;
@property(retain, nonatomic) IBOutlet Ball* mBall;



IBOutlet tells Interface Builder that we are going to bind something to the variable mBall.

Step 6

Double-click BallViewController.xib. This opens the Interface Builder.

Step 7

In Interface Builder, We are going to associate mImage with an ImageView

Drag a Image View (which really is an UIImageView object) from the Library window into your View window.


Step 8

Open Tools->Inspector, then:

a) One the Image field, select the file you imported in Step 2.
b) Set the Mode to Aspect Fit.
c) Scale the image so that it’s not too large (us the blue handles around the image to scale – if you don’t see the handles, you might need to click the View window to select the image). iphoneballimage If you’re having problem here, refer to Hello World tutorial.

Step 9

Now we need to associate the UIImageView with the Ball class.  Open Tools->Identity.  With the image still selected, select Ball on the Class selector of the Identity window.


What we have done is telling the code that the UIImageView we created should be created as an instance of the Ball class (which is derived from UIImageView), instead of the standard UIImageView class.

Step 10

Now we need to tell the code to bind the variable mBall with this instance of Ball.  Why?  Because we might have multiple Ball objects on the stage.

Open Tools->Connection Inspector, then:

a) Make sure the ImageView (the ball mage) is selected.
b) Click and drag the circle next to New Referencing Outlet to the text BallViewController in the window titled BallViewController.xib.
c) A small window will appear, where mBall should be listed.  Select mBall to bind our image to that variable.



Step 11

Close Interface Builder.  Save All.  Go Back to Xcode, and do Build and Run.  There should be no error and the app should looks something like this:



Step 12

Edit BallViewController.m.  This time, we are going to set the speed of mBall and sets a timer using scheduledTimerWithTimeInterval to move the ball.  It’s using 1/30 which is 30 fps.  Function moveBall will be called on every interval.

#import "BallViewController.h"
#import "Ball.h"

@implementation BallViewController
@synthesize mBall;

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    [NSTimer scheduledTimerWithTimeInterval:1.0/30.0 target:self
         selector:@selector(moveBall) userInfo:nil repeats:YES];   
    [mBall setSpeedX:5 Y:5];

    [mBall move];

- (void)dealloc {
    [super dealloc];
    [mBall dealloc];



Run it and see the ball bouncing and rotating.

Download the project here.

In the next tutorial, we will add more ball objects and demonstrate loading an image without using the Interface BuilderHere’s the link to the next tutorial.