Jon
Jon

Reputation: 4732

How to make Images in UITableViewCell scroll smoothly?

I'm loading images into my UITableViewCell and it is becoming choppy. I only have around 5-10 cells max.

Are there any easy ways to fix this?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"appointmentCell";

    AppointmentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    NSDictionary *appointmentDictionaryTemp = [self.appointmentArray objectAtIndex:indexPath.row];
    cell.patientNameLabel.text = [appointmentDictionaryTemp objectForKey:@"patient"];
    cell.appointmentTimeLabel.text = [appointmentDictionaryTemp objectForKey:@"scheduled_time"];

    NSString *urlString = [[appointmentDictionaryTemp objectForKey:@"patient_small_photo_url"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSData * imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
    UIImage * image = [UIImage imageWithData:imageData];
    cell.patientImage.image = image; 

    return cell;
}

Upvotes: 2

Views: 3075

Answers (5)

aopsfan
aopsfan

Reputation: 2441

Create an ivar called imageCache, which is an NSArray. Now run this code in init:

for (NSDictionary *appointmentDictionaryTemp in self.appointmentArray) {        
    NSString *urlString = [[appointmentDictionaryTemp objectForKey:@"patient_small_photo_url"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSData * imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
    UIImage * image = [UIImage imageWithData:imageData];

    [imageCache addObject:image];
}

Now in cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"appointmentCell";

    AppointmentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    NSDictionary *appointmentDictionaryTemp = [self.appointmentArray objectAtIndex:indexPath.row];
    cell.patientNameLabel.text = [appointmentDictionaryTemp objectForKey:@"patient"];
    cell.appointmentTimeLabel.text = [appointmentDictionaryTemp objectForKey:@"scheduled_time"];

    cell.patientImage.image = [imageCache objectAtIndex:indexPath.row]; 

    return cell;
}

Upvotes: 1

jbat100
jbat100

Reputation: 16827

There is an open source (MIT license) implementation of lazy/cached network of UIImageView images which you should take a look at: SDWebImage. Downloads/caches images asynchronously and automatically updates your UIImageViews.

Upvotes: 0

MCannon
MCannon

Reputation: 4041

store the images in an NSCache using the index path as the key, then in your tableView: cellForRowAtIndexPath: method, check to see if there is an object for the index path. if there is load it into the image property, and if not, then call a method to generate it. this will stop it being done every time a cell is drawn.

Upvotes: 0

Matt Wilding
Matt Wilding

Reputation: 20153

dataWithContentsOfURL: is your culprit. It performs a synchronous (blocking) network request on the application's main UI thread, causing the table view to lock up while an image is being downloaded.

The solution is much more involved, and it involves using NSURLConnection (or some other 3rd party library) to download the data asynchronously, allowing the UI to remain responsive while the image is being downloaded. This is a good resource to use for reference.

Upvotes: 2

Kai Huppmann
Kai Huppmann

Reputation: 10775

Load Images asynchronusly and maybe cache them. Start with reading this question: Lazy load images in UITableViewCell

Upvotes: 0

Related Questions