Simple image (frame-by-frame) animation in IOS and Xcode

Adding frame-by-frame animations to your iOS application is simple once you find out that a UIImageView can be initialised with an array of images, not just one image.

This post was inspired by a colleague who had not uncovered that fact, and so had spent time arduously linking separate views with timers. This post shows how to use a single view and 3 lines of animation code to do all the work.

What to do?

What we’ll do as a test is animate the blinking eyes on a tennis-playing ninja splash screen. To trigger the animation will add a “blink” button on the same screen.

Don’t ask how we ended up with that as the example (thanks to the friend). But you can download the entire project, or just the images if wanting to join in.

The steps:

  1. prepare the images
  2. create the project
  3. create/update a XIB with the image and button
  4. add the animation code and link to the same image and button

All the neat animation stuff is described in the 4th step, so feel free to scroll straight to it. The previous three steps cover all that’s needed to get your project ready to animate. I’ve included it because I hate reading articles that assume you’ve covered all the basics already. Or worse just dismiss it with one line (first step, invent time travel).

Note this process was captured in xCode4/IOS5. None of the code in here has changed much in recent releases but you may have to adjust some of the steps if running an earlier setup (one thing that has changed in this version is the options when creating a project).

(1) prepare the images

Your imagery is limited only by your artistic talents, or abilities to search Google Images or Flickr (remember to honour their copyright, boys and girls).

Only suggestion is to limit the animation element to the smallest possible; keeps sizes small. For example, for the blinking ninja, instead of 3 different ninjas with different eye positions (open, half closed, closed), I created one ninja with no eyes, and then three images of just the different eyes. What we’ll do in the project is then add the main ninja as one image view, and put the eyes over the top in a separate image.

Whatever approach you take, ensure all the images that will be animated are the same size. This will ensure when animated they appear over each other.

create the project


Crack open Xcode and choose File > New Project. I’m in the latest and greatest (4.2) so your options may vary, but for this version:

  • choose Single View Application
  • choose not to use storyboard (so we get a XIB to mess with)

Once created we have a simple project containing the key source files:

  • appDelegate.h
  • appDelegate.m
  • ViewController.h
  • ViewController.m
  • ViewController.xib

The good news is we’re only going to be editing the three ViewController files. Which means you can pretty much follow all of these steps to add an animation to an existing view within your current application; just join in from the next step.

Now add your animation images to the project. Either right-click in the folder view and select Add Files To.., or choose File > Add Files To.. from the menu.

(2) create/update XIB with the image and button

Our XIB has already been created in the project. What to do now is setup the images and buttons we meed, including the outlets needed so we can communicate with them from our code.

Firstly the images. Remember we need to add two: 1 as the background (which we don’t need to interact with) and one for the animated eyes (which we will need to talk to).

To hook things up let’s create the outlets first, and then link in the XIB. Open ViewController.h and add our definition (new text in bold):

#import 

@interface ViewController : UIViewController {
    IBOutlet UIImageView *eyesImage;
    IBOutlet UIButton *blinkButton;
}

@property (nonatomic, retain) IBOutlet UIImageView *eyesImage;
@property (nonatomic, retain) IBOutlet UIButton *blinkButton;

@end;

Then switch over to ViewController.m (tip: 3 fingers down gesture if using a trackpad) and synthesize them:

@import "ViewController.h"

@implementation ViewController

@synthesize eyesImage;
@synthesize blinkButton;

Remember if we create them, we should also destroy them:

- (void)viewDidUnload
{
    [superviewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.eyesImage = nil;
    self.blinkButton = nil;
}

That gives us our outlets so we can link to, and manipulate these items on our XIB.  Note we don’t currently need to manipulate the button but the outlet is there just in case (for example if needing to disable the button at some point).

The only other item to add in the code before we edit the XIB is the method to be called when we click the button.

Back into viewController.h and add the definition:

#import 

@interface ViewController : UIViewController {
    IBOutlet UIImageView *eyesImage;
    IBOutlet UIButton *blinkButton;
}

@property (nonatomic, retain) IBOutlet UIImageView *eyesImage;
@property (nonatomic, retain) IBOutlet UIButton *blinkButton;

- (IBAction) blink;

@end;

And then back to ViewController.m, and insert the method somewhere in the list:


- (IBAction) blink {
  //blink
}

Save the files and we’re ready to connect them to elements in the XIB.


Firstly open the XIB and drag an imageView onto the work area.
Set the size and content to be our background/static image for the animation.    Don’t worry with any outlets as we never need to talk to this image.

Now add a 2nd image view to the work area.  Set its position and size to match where the animation is to be presented.  If it helps you with positioning, set the default image to the first of your animation frames.

Once the animated image view is in place, hook up the outlet.  We need to link this to our eyesImage outlet so we can manipulate it.  Just select the Outlets panel for the view, click in the circle for Referencing Outlet and then drag to File’s Owner on the left side of the work area.  if all has worked you’ll then get a dropdown list in which you can select eyesImage.  Once selected your outlet will be added.

That’s all you need to do for the animation.  Now for the button.

Drag a Round Rect Button onto the work area and position somewhere appropriate.  Then add a suitable label (“blink” comes to mind).  View the Outlets panel for the button and drag from the Referencing Outlet to File’s Owner (as we did for the image) and select the blinkButton outlet.  And then, to link to our blink method, drag from the TouchUpInside outlet to the same File’s Owner.  If all has worked you’ll then be able to select blink and connect it up.

So that’s all the XIB sorted.  We’ve got a background/static image.  We’ve got a smaller image with an eyesImage outlet for the animation.  And we’ve got a button that when clicked will trigger our blink() method.  Only one step to go.

Save your XIB and then run your project.  You won’t see anything moving but at least your background image should be in view.

add the animation code and link to the image and button

Now for the fun part.

To animate an image we load up the image view with an array of images, set some parameters for how fast and how long the animation runs, and then start it off.  For efficiency we’ll put all the animation setup into viewDidLoad (so done once when the view first appears), and then just trigger the animation each time we click the button.

So back into viewController.m, let’s first setup the animation:

- (void)viewDidLoad
{
    [superviewDidLoad];
    
        
       //setup animation
    NSArray *eyeFrames = [NSArrayarray];
    eyeFrames = [[NSArrayalloc] initWithObjects:
                 [UIImageimageNamed:@"eyes1-open.png"],
                 [UIImageimageNamed:@"eyes2-half.png"],
                 [UIImageimageNamed:@"eyes3-closed.png"],
                 nil];
    eyesImage.animationImages = eyeFrames;
    eyesImage.animationDuration = 0.25;
    eyesImage.animationRepeatCount = 1;
    [eyeFrames release];   
    

}

We’ve added an array of three images to our eyesImage outlet. The animation will take a quarter of a second and will only run once.  Once implemented you’ll return to these settings (often!) to get the appearance just right.

Once setup, triggering it is just one line of code:

- (void) blink {
    [eyesImage startAnimating];
}

Save and run your project. Then everytime you click the button, magic happens.

Conclusion

While it took a while to get there, animating our image took only 7 lines of code.  Armed with that code you are limited by only your graphical capabilities.  Just build your images, repeat the 7 lines, and then spend an age tweaking the duration to get it looking right.  

After a while you may find this approach a bit too limited as it scrolls through the image frames at a regular pace.  If wanting a bit more control over the animation  pace, then you’ll need to step up and start using proper animation blocks.  Next time.

One thought on “Simple image (frame-by-frame) animation in IOS and Xcode

  1. Freddy

    Hi I’ve tried this method but I’ve used a storyboard as i’m doing a tabbed application, i am therfore stuck on the part where i’m linking the button, i assume that i create the images and button as usual in storyboard but i can’t connect it to the Files owner, how do i get over this?

    Thanks

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>