views:

48

answers:

1

I have a tableView with some large images in it. I'm struggling to improve the very jerky scrolling performance. If I use ImageNamed to load the images, scrolling is jerky at first, but after the images are viewed, scrolling is smooth. I know ImageNamed adds the images into the system cache, so my question is: is it possible to pre-load the images into the system cache before they are viewed?

I've tried by adding the following code to my viewDidLoad method:

for (int i = 0; i < appDelegate.detailSectionsDelegateDict.count; i++) {
         NSString *imageString = [NSString stringWithFormat:@"%@",[[appDelegate.detailSectionsDelegateDict objectAtIndex:i] objectForKey:@"MainTrackImage"]];
        NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
        UIImage* theImage;
        theImage = [UIImage imageNamed:imageString];
         [imageCacheArray insertObject:theImage atIndex:i];
}

I then draw the correct image from the imageCacheArray in my CellForRowAtIndexPath method. But the result is still jerky scrolling.

Thanks!

+3  A: 

Getting a table view with images (especially large ones) to scroll smoothly is not as trivial as you might think. Loading up a bunch of images with [UIImage imageNamed:] will very quickly cause springboard to kill your app as it starts to exceed memory capacity. Take a look at the Core Animation session videos from this year's WWDC, specifically look at session 425, "Core Animation in Practice, Part 2" They cover this exact topic and it's very well done. You can also get the relevant source code if you sign in with your developer account.

Matt Long
I'm downloading the videos now. Thanks for the tip. Just a note, I've also tried using imageWithContentsOfFile and imageWithData with the only noticeable difference being that scrolling is always jerky instead of being smooth once the images have been viewed once.
Jonah
When you're loading the images using those methods, it blocks the user interface and doesn't cache. You have to do the caching yourself. In that same session video I recommended, they cover how to load the images in a separate thread--at about 36 minutes in.
Matt Long
The problem I'm having following the code from the sample code is that I can't get it to draw all the cells before they are loaded. In their code, they use a custom viewController in which all images are drawn (whether being viewed or not). So, basically all that is happening is that the cell is being loaded lazily when it is dragged into view. Any suggestions on how to get around this? I tried creating an array of tableViewCells with the correct imageViews when the table loads and then drawing from the array in cellForRowAtIndexPath, but the performance was really bad. Thanks for the help!
Jonah
So when I've implemented this, I load the images from the scroll view delegate. UITableView is a child of UIScrollView which means it inherits all of its methods and delegates. If you wait to load the images you need when you get a -scrollViewDidEndDecelerating callback and when you get -scrollViewDidEndDragging, you can just wait until the user stops scrolling to see what images you need to load in -cellForRowAtIndexPath. Just make sure you check the decelerate flag in -scrollViewDidEndDragging and only load your images when it's set to NO. Are you caching the images?
Matt Long