I’m working on an iPhone application which displays thumbnail images from contacts in a UITableView.
Everything is very fast until I turn on the thumbnails, then it becomes very slow to scroll.
All the other data is backed by Core Data and I tried saving the images in Core Data beforehand, but this in itself takes too long at launch time and is less flexible etc.
What I really need is a way to do the lookup and prep thumbnails lazily with separate thread or NSOperation etc, but I’m not sure what the simplest way to accomplish this would be.
Apple’s sample project LazyTableImages which is fantastic if images come from the web, could surely be adapted, although I’m having a hard time with it. Basically the problem is the same, but instead of time lag from downloading and network latency etc, my delay is just the time it takes to lookup the pictures in the user’s address book.
This is the task in my table cell subclass I need to do concurrently:
UIImage *contactImage = nil;
if (ABPersonHasImageData(person)) {
NSData *contactImageData = (NSData*)ABPersonCopyImageData(person);
UIImage *tempContactImage = [UIImage imageWithData:contactImageData];
[contactImageData release];
UIGraphicsBeginImageContext(CGSizeMake(45.0f, 45.0f));
[tempContactImage drawInRect:CGRectMake(0.0f, 0.0f, 45.0f, 45.0f)];
contactImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
A big thanks to anyone who has any helpful tips or code to accomplish this in a simple and elegant way.
If you already have a UIImage, why do you need to draw into contactImage? You can just use the tempContactImage directly, no?
A good start would be to simply do this:
EDIT:
How about:
If that’s still choppy (it may be) you can queue the images you need to apply to your table view in your background thread, wait until your table view stops scrolling, then apply any pending image changes.