SDWebImage repeating images in cell instead of waiting to load.

大憨熊 提交于 2019-12-02 11:02:46

问题


I am using SDWebImage for fetching images from server to my table view app in IOS. But the problem is that when I scroll down in table view instead of waiting for the images to load it put the images downloaded in the first few rows of table view and repeat those images till the end row and when it downloads the images it changes those repeated images to the actual image for that 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:


Actually, it is not a bug with SDWebImage, but rather it's the nature of how UITableView works. downloadImageWithURL, is an async process,so when your tableView delegate/datasource methods are called, the image isn't downloaded yet, therefore cellForRow doesn't have an image to display. To overcome this issue you should first check image from cache as

[[SDWebImageManager sharedManager] diskImageExistsForURL:[NSURL URLWithString:ImageUrl]]

if yes then set image to UIImageView otherwise use downloadImageWithURL to download image and add cell tag(To display image to correct row) as

cell.tag = indexPath.row;

on successfull download first check correct row as

if(cell.tag == indexPath.row){

and set image to UIImageView.Here is 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 showProgressView and hideProgressView methods 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 cellForRowAtIndexPath method(before returning cell) as

[self setImage:cell atIndexPath:indexPath];


来源:https://stackoverflow.com/questions/26671726/sdwebimage-repeating-images-in-cell-instead-of-waiting-to-load

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!