Actually, this is not an error with SDWebImage , but rather the nature of the UITableView . downloadImageWithURL is an asynchronous process, so when you call the delegate / datasource tableView methods, the image is not yet loaded, so cellForRow does not have an image to display. To overcome this problem, you must first check the image from the cache as
[[SDWebImageManager sharedManager] diskImageExistsForURL:[NSURL URLWithString:ImageUrl]]
if so, set the image to UIImageView, otherwise use downloadImageWithURL to load the image and add a cell label (to display the image to correct the row) as
cell.tag = indexPath.row;
on successful download, first check the correct line as
if(cell.tag == indexPath.row){
and set the image to UIImageView. Here is the setImage method.
-(void)setImage:(SLFirstTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath{ SLFirstTableViewCellItem * slFirstTableViewCellItem = [self.categories objectAtIndex:indexPath.row]; // categories is array of items,replace with yours. NSString *ImageUrl = slFirstTableViewCellItem.imageUrl; //assume image url is in slFirstTableViewCellItem object. cell.tag = indexPath.row; if([[SDWebImageManager sharedManager] diskImageExistsForURL:[NSURL URLWithString:ImageUrl]]){ [cell.imgItem setImage: [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:ImageUrl]]; [self hideProgressView:cell]; }else{ [self showProgressView:cell]; [SDWebImageDownloader.sharedDownloader downloadImageWithURL:[NSURL URLWithString:ImageUrl] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { // progression tracking code } completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { if (image && finished) { [[SDImageCache sharedImageCache] storeImage:image forKey:ImageUrl]; // cache image if(cell.tag == indexPath.row){ // check if correct row [cell.imgItem setImage:image]; [self hideProgressView:cell]; } }else{ cell.imgItem.hidden = YES; cell.progressBar.hidden = YES; } }]; } }
And define the showProgressView and hideProgressView as
-(void)showProgressView:(SLFirstTableViewCell *)cell { cell.progressText.hidden = NO; cell.progressBar.hidden = NO; cell.imgItem.hidden = YES; [cell.progressBar startAnimating]; [cell.progressText setText:@"Loading Image..."]; } -(void)hideProgressView:(SLFirstTableViewCell *)cell{ cell.progressBar.hidden = YES; cell.progressText.hidden = YES; cell.imgItem.hidden = NO; [cell.progressBar stopAnimating]; }
finally call setImage from setImage method (before returning the cell) as
[self setImage:cell atIndexPath:indexPath]
Giru bhai
source share