The right approach to loading dynamic content into a UITableView in iOS

Go To StackoverFlow.com

0

ok, I've read tons of bits and pieces on the subject of loading dynamic content (from the web) into a UITableView and the problem with calculating cell height upfront. I've tried different simple implementations but the problem persists...

Assuming I need to read a JSON file from the web, parse it into 'item' objects, each with variable size image and various text labels, here is what I believe would be the right approach to avoid long hang time of the app while everything is loading:

  1. on app load read JSON file and parse into items array
  2. provide only small part of the items array to the tableview (about 10 items) - since I need to load the images associated with each item to calculate cell height - I don't want the view to go through the whole items list and load all images - this hangs the app until every image is loaded
  3. display the tableview with the available cells (assuming I load a few 'spare' ones, user can even scroll to more items)
  4. in the background using Grand Central Dispatch download images for all/some of the remaining items and then reload the tableview with the new data (repeat step 4 if item list is very long)

Step 2 above is necessary since I have no way to calculate the cell height without loading the images first, and since tableview first calculates height of all cells it may take a very long time to download all images for all items.

Would you say this is the right approach? am I missing something?

2012-04-03 21:08
by OS.


2

Why don't you standardize in the tableview the image size. Then you can manipulate the images as they are displayed to fit the size. Offer a way to view the image if selected. The Quartzcore framework will allow you to take your original images and size them.

I only suggest this because it would make your tableview look more appealing with uniform picture sizes than with random ones.

2012-04-03 21:41
by Nungster
Agreed. Take the Flickr approach and crop them to a uniform square size - Wayne Hartman 2012-04-03 21:43


0

You're right that the show must go on, even while your data is still loading. So you'll want to design a cell that looks attractive before it has the correct image. A common approach is to ship a default image and format the cell so that looks good.

To handle the height, the tableView datasource protocol can ask you how tall a cell should be. The way to answer is, in pseudo code:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

  id myModelElement = [self.myModel objectAtIndex:indexPath.row];
  UIImage *image = myModelElement.image;
  if (!image) image = self.placeholderImage;

  return kFIXED_HEIGHT + image.size.height;
}

You're also correct that you'll want to load the images asynchronously. See my answer here for a very simple approach to that. No GCD, not even a table row reload.

2012-04-03 23:25
by danh
Danh, if I calculate cell height in heightFor... Then I must first load all images... That's what's I'm trying to avoi - OS. 2012-04-05 03:14
Right, you might not have images loaded yet, but you still need a row height. This is why I suggest a placeholder - an image shipped in your app bundle that looks pretty until a real one arrives - danh 2012-04-05 03:55