Improving iPhone App User Experiences with Activity Indicators
Posted by AVAI Mobile Developer on Tue, Nov 17, 2009 @ 11:25 PM
When developing mobile applications, user interface design is one of the most crucial elements that you need to worry about. Users are already restricted to a tiny keyboard and 3.5" screen, so they start out having less patience than they would for say, a desktop application. With that in mind, whenever an application has to perform a task that takes more than half a second, such as downloading data, or doing a lot of computation, the user needs to be notified with an activity indicator view or progress view that the app is still working, and has not simply frozen.
So how do we add an activity indicator to notify the user when the application is working? You might assume that you can add a UIActivityIndicator in Interface Builder, link it up with an outlet in your view controller, and just call the startAnimating and stopAnimating methods before and after the code for downloading images. With this method, the view will not actually be loaded on the screen until after the images are downloaded, so you will never even see the activity indicator. This is because the downloading of images is occurring in the main thread, which also happens to be the one used for UI updates. So, while fetching images, the UI thread is blocked from doing updates, so your activity indicator doesn't appear until it's done.
The solution is to download images in another thread, and call back the main thread when you're done. This can be done with the performSelectorInBackground and performSelectorOnMainThread methods from the NSObject class. The code below outlines the method just described.
- (void)viewDidLoad
{
[self.activityIndicator startAnimating];
[NSThread detachNewThreadSelector:@selector(downloadImages) toTarget:self withObject:nil];
[super viewDidLoad];
}
-(void) downloadImages
{
//Download images here
//Once the download is complete, go load the downloaded images into the table.
[self performSelectorOnMainThread:@selector(loadTable) withObject:nil waitUntilDone:NO];
}
-(void) loadTable
{
[self.activityIndicator stopAnimating];
[self.tableView reloadData];
}
Richard