0

I have a table that displays images. It can be searched live, which adjusts the cells being displayed. The images are loaded in the background using a concurrent NSOperation subclass over the network when the image is not already immediately available.

After the image has been fetched, I want to update the table to display it.

How can I update the right cell?

  • I cannot rely on the cell that I have built in tableView:cellForRowAtIndexPath:, because the cell may have been repurposed for another row.
  • I cannot rely on the indexPath passed into tableView:cellForRowAtIndexPath:, because it may have changed since the update began due to a search term change.
  • I cannot search the visible cells in the table, because the cells themselves are instances of UITableViewCell and have no metadata.
  • I cannot search my filtered list, because I don't know what table to apply the changes to.

What am I missing?

Steven Fisher
  • 44,462
  • 20
  • 138
  • 192

2 Answers2

2

I do this exact operation in my app in the app store. I created a notification handler in my view controller that gets notified when an image arrives. That image has tag associated with it - something I can map to the view that needs it.

When a cell is created, I add a UIImageView to the contentViews array, with a unique tag that matches the tag associated with the image (and you can offset these with like 10,000 to avoid conflicts).

Then I ask the UITableView for the array of visible cells. I iterate through them, asking each cell's contentView for a viewWithTag:tag (the unique tag). If found, I have the right UIImageView, and I set the image.

Obviously when providing cells to the tableView, you have to always provide the proper tag to the ImageView.

David H
  • 40,852
  • 12
  • 92
  • 138
1

The simplest solution is probably just to subclass UITableViewCell to add a tracking property. Something like this:

@interface TrackingTableViewCell : UITableViewCell
@property (strong) id trackingValue;
@end;

@implementation TrackingTableViewCell
// Default @synthesize as of Xcode 4.4!
@end

When you set up the cell, set the trackingValue to the NSURL you are downloading the URL from. When you finish loading the image, check the trackingValue of the visible cells. If you find one that matches, great. If not, don't set it anywhere.

You could theoretically do the same thing with the objc_setAssociatedObject() API, but I don't really see the value in doing that over just creating a simple subclass to track the value for you.

BJ Homer
  • 48,806
  • 11
  • 116
  • 129
  • I like this idea. Related: How do you find out which tableview is being displayed? Or should I always search both of them? – Steven Fisher Jul 25 '12 at 22:02
  • You could ask both tableViews for -indexPathForCell:, to quickly determine which one (if any) the cell is visible in. – BJ Homer Jul 25 '12 at 22:14
  • Thanks. The answer worked out great. I ended up going with `UITableView *tableToSearch = self.searchDisplayController.active ? self.searchDisplayController.searchResultsTableView : self.tableView;` and searching its visibleCells for cells of the correct subclass, then comparing the tracking value as you suggested. – Steven Fisher Jul 25 '12 at 22:34