SDWebImage repeats images in a cell instead of waiting for a download.

I am using SDWebImage to retrieve images from a server in an application to view a table in iOS. But the problem is that when I look at the table view instead of waiting for the images to load, it loads the images loaded in the first few rows of the table and repeats these images to the end of the line, and when it loads the images, it changes those duplicate images to actual image for this row.

NSURL * url = [NSURL URLWithString:string]; SDWebImageManager *manager = [SDWebImageManager sharedManager]; [manager downloadImageWithURL:url options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { // progression tracking code } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished,NSURL * url) { if (finished && image ) { NSArray *visibleIndexPaths = [tableView indexPathsForVisibleRows]; if ([visibleIndexPaths containsObject:indexPath]) { cell.myImage.image = image; } } }]; 
+1
ios image scroll repeat sdwebimage
source share
1 answer

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]; 
+2
source share

All Articles