3

The problem i'm facing is to add a bunch of images next to each other vertically and make the whole thing scrollable. The images are 768x768. I'm using UITableView for this.

First i've tried to do it simply by dequeueing a single cell in the following method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Since my device only fits one and a half of such images vertically - i got a lag every time a new image was about to be loaded.

So ... i thought i'd simply test things by caching all cells in an array on application load. So now in my method for retrieving a cell looks like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    PhotoItemCellController *cell = [imgs objectAtIndex:[indexPath row]];
    return cell;
}

Here's the weird thing: all of this is the same as loading the images dynamically whenever needed - there is still the same lag... But ... when i scroll through the entire table to the end of it - the table begins to work flawlessly (obviously some sort of caching occurs).

  • Why does this happen?
  • Could it be because i'm using an array of cells instead of "dequeueing" them from table?
  • Could it be because the cells contain UIImageView? Maybe it does something the first time it's shown.

Also i notice a spike in RAM usage only when i scroll through the table, and there's virtually no consumption when i load all cells with their images in memory on app launch.

Any thoughts appreciated

Marius
  • 3,976
  • 5
  • 37
  • 52
  • You should not store cells in an array. This removes lots of the optimization that UITableView can do for you. Can you post your `cellForRowAtIndexPath` method before the array business? – Aaron Brager Jun 19 '13 at 22:36
  • I don't think the problem is slow speed creating the cells--it's slow speed loading the images and getting them ready for view. – Idles Jun 19 '13 at 22:37
  • How big are your images actually displayed? You could try to resize them to the correct size before displaying them. The will reduce the time it takes to display them on screen. The re-size process can be done beforehand in a background thread if needed – Robert Jun 19 '13 at 22:40
  • He already said 768x768. I think it's likely that this is a portrait-mode iPad application, so the images are already the correct size (they would span the full width of the iPad). – Idles Jun 19 '13 at 22:42
  • @Robert The problem is definitely not with the image size. Like i said - after the first scroll it very smoothly. – Marius Jun 19 '13 at 22:45

2 Answers2

1

UIImage is backed by some kind of intelligent cache that's capable of lazy loading. It's quite likely that the image files aren't ever loaded into memory until they're needed. There's also a bit of delay when creating an OpenGL texture for your image (UIKit does this behind the scenes, since it uses OpenGL to render). If you just want smooth scrolling, you could display a spinner in the foreground, and create a series of UIImageViews that you display one-by-one behind the UITableView (and you keep the UIImageViews around for generating your cells). That way you'll have all the data cached and (hopefully) in the OpenGL context in textures before the user starts scrolling.

Idles
  • 1,131
  • 5
  • 9
  • I think you are right about this. That would explain the weird RAM usage. I'll have to try your solution to see if it helps. – Marius Jun 19 '13 at 22:46
  • Along these lines, you could try rendering them in a separate context, that may force them to load without showing to the screen. – Kevin Jun 19 '13 at 23:18
  • @Kevin - if only i knew how :) iOS graphics is a bit of a mystery to me. – Marius Jun 19 '13 at 23:31
  • @Marius Try the code in [this post](http://stackoverflow.com/a/4469273/900873). Instead of a new size, just use the original. – Kevin Jun 20 '13 at 02:50
  • @Kevin thanks a lot for the post. I've already gone the CATiledLayer path with UIScrollView though. Seems more suitable to the situation. – Marius Jun 20 '13 at 02:58
0

I highly recommend watching the 2010 & 2012 WWDC videos Designing Apps with Scroll Views and Enhancing User Experience with Scroll Views as they address your issues. While the first video provides a legacy manual approach the second video has updated iOS6 methods that greatly simplifies the code via using UIPageViewControllers. There are some pretty good talking points regarding killing images out of memory when they're not directly in view as well as constructing the images when they're about to be needed.

Dan
  • 5,153
  • 4
  • 31
  • 42
  • Thank you, watching it now. I came to the same conclusion of using scroll views with tiled layers, but didn't know how to implement it. Hopefully the videos will be helpful. – Marius Jun 20 '13 at 00:10
  • Video links are not available. – The iCoder Jan 22 '14 at 09:47
  • The links work for me. You have to login to the Apple Developer Portal to see the list. – Dan Jan 22 '14 at 13:03