2

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;
}
Jon
  • 4,732
  • 6
  • 44
  • 67
  • 1
    the main problem is in [NSData dataWithContentsOfURL:...] that block your app till the download is completed. To me the easy and faster way to solve this is to use the AFNetworking lib: on it's site you can find some useful expamples on how to download images... – il Malvagio Dottor Prosciutto Nov 16 '11 at 23:39

5 Answers5

2

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.

Matt Wilding
  • 20,115
  • 3
  • 67
  • 95
1

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;
}
aopsfan
  • 2,451
  • 19
  • 30
0

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

Community
  • 1
  • 1
Kai Huppmann
  • 10,705
  • 6
  • 47
  • 78
0

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.

MCannon
  • 4,011
  • 2
  • 16
  • 12
0

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.

jbat100
  • 16,757
  • 4
  • 45
  • 70