Antonio MG
Antonio MG

Reputation: 20410

Lazy loading of image in tableview

Im trying to load the image of my uitableviewcells in lazy mode.

I'm trying to do it in the simplest possible way, I saw a lot of examples but they were going further than my purpose.

This is what Im doing currently, and its not working:

// Configure the cell...
    Info *info = [self.Array objectAtIndex:indexPath.row];
    cell.textLabel.text = info.name;
    cell.detailTextLabel.text = info.platform;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;


    //The image is downloaded in asynchronous 

    NSBlockOperation *downloadingImgBlock = [NSBlockOperation blockOperationWithBlock:^{
        NSString* imageURL = info.imgURL;
        NSData* imageData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:imageURL]];
        cell.imageView.image = [UIImage imageWithData:imageData];
    }];
[self.queue addOperation:downloadingImgBlock];

Why it's not working? And how could it work?

Upvotes: 1

Views: 2392

Answers (5)

Antonio MG
Antonio MG

Reputation: 20410

I finally managed to do it setting the image with:

– performSelectorOnMainThread:withObject:waitUntilDone:

After the image is downloaded

Upvotes: 0

jacerate
jacerate

Reputation: 456

Using the 3rd party library source code would be easiest, but here's how you would do it in code. You are going to want to make a NSMutableArray either as a property in your .h or at the top of your .m like this:

@implementation viewController{
     NSMutableArray *picList;
}

and in -initWithCoder: or, whatever init you are overloading:

picList = [[NSMutableArray alloc] init]; 

in – tableView:cellForRowAtIndexPath: (fullPicURL is the URL):

if([self imageExists:fullPicURL]){

    shoePic = [picList objectForKey:fullSmallPicURL];   

} else {

    NSURL *picURL = [NSURL URLWithString:fullPicURL];

    shoePic = [UIImage imageWithData:[NSData dataWithContentsOfURL:picURL]];
    NSDictionary *thisImage = [NSDictionary dictionaryWithObject:shoePic forKey:fullSmallPicURL];
    [cachedImages addEntriesFromDictionary:thisImage];
} 

where -imageExists: is a function you write which checks the dictionary for the url. The object is the picture itself, the key is the url. Then you do cell.image = showPic;, or whatever you want to call it, and you're done for cacheing. In order to load them asynchronously, do this:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSData *data = [NSData dataWithContentsOfURL:shoes];
    [self performSelectorOnMainThread:@selector(fetchedShoeData:) withObject:data waitUntilDone:YES];

});

and at the end of fetchedData:

[self.tableView reloadData];

then just make sure you edit –numberOfSectionsInTableView: to change itself if it has to. Might be some other things you need to do to get it working 100%, let me know

Upvotes: 1

holex
holex

Reputation: 24031

try this one, I'm using always this scheme to load images asynchronously:

(I haven't found simplest way.)

- (void)inAnyMethod {

    // ...

    void (^blockLoadPhoto)() =  ^{
        UIImage *_imageTemporary = [UIImage imageNamed:@"..."];
        if (_imageTemporary) {
            [self performSelectorOnMainThread:@selector(setPhoto:) withObject:_imageTemporary waitUntilDone:true];
        }
    };

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), blockLoadPhoto);

    // ...

}

- (void)setPhoto:(UIImage *)photo {
    // do something with the loaded image
}

Upvotes: 0

lu yuan
lu yuan

Reputation: 7227

Try the following codes

  ......
  __block UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

  __block UIImage *img;
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString: imageURL]]];

        dispatch_async(dispatch_get_main_queue(),^{

            cell.imageView.image = img;

            }
        });


    });
  ......

Upvotes: 1

Fran Sevillano
Fran Sevillano

Reputation: 8163

Man, AsyncImageView is your friend! Just set the image url and everything is handled for you, downloading, caching. It's awesome.

Upvotes: 5

Related Questions