Vikings
Vikings

Reputation: 2527

Table View Cell With Image

I have a table view cell with two image views, one image view is a placeholder, and on top of the other image is the actual image I load from the documents directory. I am having issues with the image being incorrectly displayed when the table view resuses the cell.

I solved my problem by using the below method in the cell class, but I have read that this can cause performance issues, any ideas on a better solution?

- (void)prepareForReuse
{
    [[self imageView] setImage:nil];
}

Upvotes: 1

Views: 701

Answers (2)

Matthias Bauch
Matthias Bauch

Reputation: 90117

First of all, you are not calling [super prepareForReuse] like you should.

And the documentation is pretty clear, you should be setting the image in tableView:cellForRowAtIndexPath: because it's content.
If you set the image in tableView:cellForRowAtIndexPath: there is no point to set it to nil in prepareForReuse.

Imagine the following flow.

  1. You scroll down, cell 0 is put onto the queue.
  2. prepareForReuse sets imageView.image to nil
  3. tableView:cellForRowAtIndexPath: dequeues the cell and sets imageView.image to image1

You are setting imageView.image twice.

If you use nil there might be no measurable performance impact at all. But you might come to the idea to actually set a placeHolder image. So the cell is queued and prepared for reuse, you set the placeholder image; later the cell is dequeued and the placeholder image is replaced by a real image before the placeholder image was even visible.

I would remove the prepareForReuse method completely. You don't need it if you set the image in tableView:cellForRowAtIndexPath:


from the documentation:

If a UITableViewCell object is reusable—that is, it has a reuse identifier—this method is invoked just before the object is returned from the UITableView method dequeueReusableCellWithIdentifier:. For performance reasons, you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state. The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell. If the cell object does not have an associated reuse identifier, this method is not called. If you override this method, you must be sure to invoke the superclass implementation.

Upvotes: 2

Thilina Chamath Hewagama
Thilina Chamath Hewagama

Reputation: 9040

Since you have a placeholder image behind this image view, There is nothing wrong if you set the top imageview's image to nil.

To enhance the image generating process, you can use a NSCache object like this,

1)

@property(nonatomic, strong) NSCache *imageCache;


2) Call this methods inside tableView cellForRowAtIndexPath: method, the image generating process can be moved into this,

-(UIImage *) imageForIndexPathRow:(int) row{

    id image = [self.imageCache objectForKey:[NSNumber numberWithInt:row]];

    if(!image){//if the image is not in the cache,

        UIImage *newImage; //create image here

        [self.imageCache setObject:newImage forKey:[NSNumber numberWithInt:row]];

        return newImage;
    }

    return (UIImage *) image;
}

Upvotes: 0

Related Questions