I haven't done this myself, but my idea would be to create my own UIView subclass that handles showing the UIActivity indicator while the image is loading. Then add instances of that view to your table cells instead of plain UIImageViews.
Update:
OK, as I said before, I haven't done this myself. The following is just typed into the browser, and I'm not sure if you'd run into any issues with threading, but it should give you an idea as to how to approach this:
@interface IndicatorImageView : UIView {
UIImageView *imageView;
UIActivityIndicatorView *indicator;
NSString *imageName;
NSURL *imageURL;
}
@property (nonatomic, copy) NSString *imageName;
@property (nonatomic, retain) NSURL* imageURL;
@end
@implementation IndicatorImageView
@synthesize imageName;
@synthesize imageURL;
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
imageView = [[UIImageView alloc] initWithFrame:self.bounds];
[self addSubview:imageView];
indicator = [[UIActivityIndicatorView alloc] initWithFrame:self.bounds];
[self addSubview:indicator];
}
return self;
}
- (void)setImageName:(NSString *)anImageName {
if (imageName == anImageName) {
return;
}
[imageName release];
imageName = [anImageName copy];
// optionally remove the old image while we're updating
//imageView.image = nil;
[indicator startAnimating];
[self performSelectorInBackground:@selector(updateImageViewUsingImageName) withObject:nil];
}
- (void)setImageURL:(NSURL *)anImageURL {
if (imageURL == anImageURL) {
return;
}
[imageURL release];
imageURL = [anImageURL copy];
// optionally remove the old image while we're updating
//imageView.image = nil;
[indicator startAnimating];
[self performSelectorInBackground:@selector(updateImageViewUsingImageURL) withObject:nil];
}
- (void)updateImageViewUsingImageName {
NSAutoreleasepool *pool = [[NSAutoreleasePool alloc] init];
imageView.image = [UIImage imageNamed:imageName];
[indicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil];
[pool release];
}
- (void)updateImageViewUsingImageURL {
NSAutoreleasepool *pool = [[NSAutoreleasePool alloc] init];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
imageView.image = [UIImage imageWithData:imageData];
[indicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil];
[pool release];
}
@end
When you set the imageName
property, the image will be loaded in the background while the UIActivityIndicatorView
is animating. Once the image is loaded and set on the UIImageView
, we stop animating the activity indicator.