Reputation: 20410
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
Reputation: 20410
I finally managed to do it setting the image with:
– performSelectorOnMainThread:withObject:waitUntilDone:
After the image is downloaded
Upvotes: 0
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
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
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
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