iPhone Application Development : Creating and Managing Image Animations and Sliders (part 2) - Adding an Image View

1/30/2011 9:52:04 AM

Adding an Image View

In this exercise, our view creation will begin with the most important object of the project: the image view (UIImageView). Open the Interface Builder Objects Library and drag an image view into the view window.

Because the view is has no images assigned, it will be represented by a light-gray rectangle. Use the resize handles on the rectangle to size it to fit in the upper two-thirds of the interface (see Figure 2).

Figure 2. Set the image view to fill the upper two-thirds of the iPhone interface.

Setting the Default Image

There are very few attributes for configuring the functionality of an image view. In fact, there is only one: the image that is going to be displayed. Select the image view and press Command+1 to open the Attributes Inspector (see Figure 3).

Figure 3. Set the image that will be shown in the view.

Using the Image drop-down menu, choose one of the image resources available. This will be the image that is shown before the animation runs, so using the first frame (frame-1.png) is a good choice.

By the Way

What about the animation? Isn’t this just a frame? Yes, if we don’t do anything else, the image view will show a single static image. To display an animation, we need to create an array with all the frames and supply it programmatically to the image view object. We do this in a few minutes, so just hang in there!

The image view will update in Interface Builder to show the image resource that you’ve chosen.

You Said You’d Tell Us About Loading Hi-Res Images for the iPhone 4. How Do We Do It?

That’s the best part! There’s really nothing to do that you don’t already know. To accommodate the higher scaling factor of the iPhone 4, you just create image resources that are two times the horizontal and vertical resolution, and then name them with the same filename as your original low-res images, but with the suffix @2x (for example, Image.png becomes Image@2x.png). Finally, add them to your project resources like any other resource.

Within your projects, just reference the low-res image, and the hi-res image is loaded automatically on the correct devices, as needed!

Connecting to the Outlet

To display an animation, we need to access the object from the ImageHop view controller. Let’s connect the image view to the imageView outlet that we created earlier.

Within the Document window, Control-drag from the File’s Owner icon to the image view icon in the Document window or to the graphical representation in the view window. When prompted for the outlet, choose imageView, as shown in Figure 4.

Figure 4. Connect the image view to an outlet so that it can be easily accessed from code.

Now that the image view has been added, let’s look at the code we need to add to change from a static image to an animation.

Animating the Image View

To truly customize an image view, we need to write some code. Animating images requires us to build an array of image objects (UIImage) and pass them to the image view. Where should we do this? As with the last project, the ViewDidLoad method of our view controller provides a convenient location for doing additional setup for the view, so that’s what we’ll use.

Switch back into Xcode, and open the view controller implementation file, ImageHopViewController.m. Find the ViewDidLoad method and uncomment it, and then add the following code to the method. Note that we’ve removed lines 7–20 to save space (they follow the same pattern as lines 4–6 and 21–23), as shown in Listing 2.

 1: - (void)viewDidLoad {
2: NSArray *hopAnimation;
3: hopAnimation=[[NSArray alloc] initWithObjects:
4: [UIImage imageNamed:@"frame-1.png"],
5: [UIImage imageNamed:@"frame-2.png"],
6: [UIImage imageNamed:@"frame-3.png"],
21: [UIImage imageNamed:@"frame-18.png"],
22: [UIImage imageNamed:@"frame-19.png"],
23: [UIImage imageNamed:@"frame-20.png"],
24: nil
25: ];
26: imageView.animationImages=hopAnimation;
27: imageView.animationDuration=1;
28: [hopAnimation release];
29: [super viewDidLoad];
30: }

To configure the image view for animation, first an array (NSArray) variable is declared (line 2) called hopAnimation. Next, in line 3, the array is allocated and initialized via the NSArray instance method initWithObjects. This method takes a comma-separated list of objects, ending with nil, and returns an array.

The image objects (UIImage) are initialized and added to the array in lines 4–24. Remember that you’ll need to fill in lines 7–20 on your own; otherwise, several frames will be missing from the animation!

Once an array is populated with image objects, it can be used to set up the animation of an image view. To do this, set the animationImages property of the image view (imageView) to the array. Line 6 accomplishes this for our example project.

Another image view property that we’ll want to set right away is the animationDuration. This is the number of seconds it takes for a single cycle of the animation to be played. If the duration is not set, the playback rate will be 30 frames per second. To start, our animation will be set to play all the frames in 1 second, so line 27 sets the imageView.animationDuration to 1.

Finally, in line 28, we’re finished with the hopAnimation array, so it can be released.

Starting and Stopping the Animation

A little later in this tutorial, we’ll be adding controls to change the animation speed and to start/stop the animation loop. You’ve just learned how the animationDuration property can change the animation speed, but we’ll need three more properties/methods to accomplish everything we want:

isAnimating: This property returns true if the image view is currently animating its contents.

startAnimating: Starts the animation.

stopAnimating: Stops the animation if it is running.

If you run the application now, it will work, but only a static image will display. The image view does not start animating until the startAnimating method is called. We’ll take care of that when implementing the view controller logic.

Adding a Slider

The next piece that our interface needs is the slider that will control the speed. Return to Interface Builder and the view, and then navigate to the Objects Library and drag the slider (UISlider) into the view, just under the image view. Using the resize handles on the slider, click and drag to size it to about two-thirds of the image view width and align it with the right side of the image view. This leaves just enough room for a label to the left of the slider.

Because a slider has no visual indication of its purpose, it’s a good idea to always label sliders so that your users will understand what they do. Drag a label object (UILabel) from the Library into your view. Double-click the text and set it to read Speed:. Position it so that it is aligned with the slider, as shown in Figure 5.

Figure 5. Add the slider and a corresponding label to the view.

Setting the Slider Range Attributes

Sliders make their current settings available through a value property that we’ll be accessing in the view controller. To change the range of values that can be returned, we need to edit the slider attributes. Click to select the slider in the view, and then open the Attributes Inspector (Command+1), as shown in Figure 6.

Figure 6. Edit the slider’s attributes to control the range of values it returns.

The Minimum, Maximum, and Initial fields should be changed to contain the smallest, largest, and starting values for the slider. For this project, use .25, 1.75, and 1.0, respectively.

Where Did These Min, Max, and Initial Values Come From?

This is a great question, and one that doesn’t have a clearly defined answer. In this application, the slider represents the speed of the animation, which, as we’ve discussed, is set through the animationDuration property of the image view as the number of seconds it takes to show a full cycle of an animation. Unfortunately, this means the faster animations would use smaller numbers and slower animations use larger numbers, which is the exact opposite of traditional user interfaces where “slow” is on the left and “fast” is on the right. Because of this, we need to reverse the scale. In other words, we want the big number (1.75) to appear when the slider is on the left side and the small number (.25) on the right.

To reverse the scale, we take the combined total of the minimum and maximum (1.75 + 0.25), and subtract the value returned by the slider from that total. For example, when the slider returns 1.75 at the top of the scale, we’ll calculate a duration of 2 – 1.75, or 0.25. At the bottom of the scale, the calculation will be 2 – 0.25, or 1.75.

Our initial value will be 1.0, which falls directly in the middle of the scale.

Make sure the Continuous check box isn’t checked. This option, when enabled, will have the control to generate a series of events as the user drags back and forth on the slider. When it isn’t enabled, events are generated only when the user lifts his or her finger from the screen. For our application, this makes the most sense and is certainly the least resource-intensive option.

The slider can also be configured with images at the minimum and maximum sliders of the control. Use the Min Image and Max Image drop-downs to select a project image resource if you’d like to use this feature. (We’re not using it in this project.)

Connecting to the Outlet

For convenient access to the slider, we created an outlet, animationSpeed, that we’ll be using in the view controller. To connect the slider to the outlet, Control-drag from the File’s Owner icon to the slider object in the view or the slider icon in the Document window. When prompted, choose the animationSpeed outlet.

By the Way

In case you’re wondering, it’s certainly possible to implement this application without an outlet for the slider. When the slider triggers an action, we could use the sender variable to reference the slider value property. That said, this approach will allow us to access the slider properties anywhere in the view controller, not just when the slider triggers an action.

Connecting to the Action

When a user drags the slider and releases his finger, the application should trigger the action method setSpeed. Create this connection by selecting the slider and then opening the Connections Inspector (Command+2).

Drag from the circle beside Value Changed to the File’s Owner icon in the Document window. When prompted, choose to connect to the setSpeed action. Once complete, Connections Inspector should reflect this change and show both the setSpeed and animationSpeed connections, as demonstrated in Figure 7.

Figure 7. When the user drags and releases the slider, the setSpeed method is called.

That completes the major parts of the UI, but there’s still some cleanup work to do.

  •  iPhone Application Development : Creating and Managing Image Animations and Sliders (part 1)
  •  iPhone Application Development : User Input and Output
  •  Windows Phone 7 : Using Accelerometer Data to Move a Ball
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 4) - Device Libraries
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 3) - Transcoders
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 2) - Detecting the Context
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 1) - HTTP
  •  Using Windows Phone 7 Technologies : Retrieving Accelerometer Data (part 2)
  •  Using Windows Phone 7 Technologies : Retrieving Accelerometer Data (part 1)
  •  Using Windows Phone 7 Technologies : Understanding Orientation and Movement
  •  Programming the Mobile Web : HTML 5 (part 4) - Client Storage
  •  Programming the Mobile Web : HTML 5 (part 3) - Offline Operation
  •  Programming the Mobile Web : HTML 5 (part 2) - The canvas Element
  •  Programming the Mobile Web : HTML 5 (part 1)
  •  Windows Phone 7 : Submitting Your First Windows Phone Application to the Windows Phone Marketplace
  •  Windows Phone 7 : Packaging, Publishing, and Managing Applications
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 3)
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 2)
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 1)
  •  Programming the Mobile Web : Mobile Rich Internet Applications (part 2) - JavaScript Mobile UI Patterns
    Top 10
    Visual Studio 2010 : Understanding Solutions and Projects (part 1)
    Programming .NET Security : Programming Asymmetrical Encryption
    Microsoft XNA Game Studio 3.0 : Writing Your First Program (part 1)
    Programming Excel with VBA and .NET : Variables (part 3) - Constants, Enumerations & Arrays
    Windows Server 2008 : Synchronizing Directory Information with Forefront Identity Manager (FIM)
    Maintaining Windows 7 with Backup and Restore (part 2) - Using Advanced Backup Options & Using System Protection
    Windows Phone 7 Development : Working with Video (part 1)
    Windows Server 2003 : Installing and Configuring Domain Controllers
    Network Programming with Windows Sockets : A Thread-Safe DLL for Socket Messages
    Algorithms for Compiler Design: LEXICAL ANALYZER DESIGN
    Most View
    Parallel Programming with Microsoft .Net : Parallel Aggregation - Design Notes
    Optimizing for Vertical Search : The Opportunities in Vertical Search
    Managing Windows Firewall in Windows Vista
    Java Mobile Edition Security : Configurations, Profiles, and JSRs
    Windows 7 : Working with the Windows Firewall (part 2) - Configuring Security for the Basic Windows Firewall & Troubleshooting the Basic Windows Firewall
    Exploring the T-SQL Enhancements in SQL Server 2005 : The PIVOT and UNPIVOT Operators
    Windows 7 : Managing the BCD Data Store
    Exchange Server 2010 : Installing OCS 2007 R2 (part 3) - Configuring Prerequisites & Deploying an OCS 2007 Server
    SQL Azure: Building a Shard (part 4) - Updating and Deleting Records in the Shard & Adding Records to the Shard
    Internet Explorer Security Settings
    Silverlight Recipes : Managing XAML Resources
    Working with File and Data Management Policies in Vista
    Windows Server 2008 : Transport-Level Security - Using IPSec Encryption with Windows Server 2008 R2
    Managing Exchange Server 2010 : Archiving and compliancy (part 3) - Discovery
    Algorithms for Compiler Design: WHY LR PARSING IS ATTRACTIVE
    SharePoint 2010 : Implementing Authentication Scenarios
    Optimizing for Vertical Search : Optimizing for Image Search (part 2) - Optimizing Through Flickr and Other Image Sharing Sites
    SharePoint 2010 : Upgrading an Existing Extranet Solution from SharePoint 2007
    iPhone Programming : Creating a Table View
    SQL Server 2008 : T-SQL Stored Procedure Coding Guidelines