【问题标题】:SDWebImage + UITableViewCell, wrong image when scrolling?SDWebImage + UITableViewCell,滚动时图像错误?
【发布时间】:2017-09-05 16:56:59
【问题描述】:

我在使用 SDWebImage 将图像加载到自定义 UITableViewCell 内的 UIImageView 时遇到问题。 这是我在 UITableView 代表处的代码:

    static NSString *userTableId = @"userTableId";
    UserDetailsTableViewCell *cell = (UserDetailsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:userTableId];
    NSDictionary *user = [userList objectAtIndex:indexPath.row];
    NSInteger position = indexPath.row + 1;
    [cell.userDetailsView loadFromDictionary:user WithIndex:position ForCharitie:false];
        cell.userDetailsView.delegate = self;

    cell.userDetailsView.delegate = self;
    return cell;

这是我的 loadFromDictionary 代码:

-(void) loadFromDictionary: (NSDictionary *) dic  WithIndex: (NSInteger) index ForCharitie: (BOOL) isCharitie{
    NSDictionary *userImageDic = [dic objectForKey:@"image"];
    NSString *url =[userImageDic objectForKey:@"url"];

    [userImage setImage:[UIImage imageNamed:@"defaultAvatar"]];
    if ([url class] != [NSNull class]){
        [userImage setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"defaultAvatar"]];
    }
}

现在,问题是如果我在某些图像完成加载之前向下滚动。例如,假设我看到前 8 行,并且第 1、2 和 3 行仍在加载它们的图像,现在我滚动到 9-16,我看到所有它们的 defaultAvatar,几秒钟后(我猜测当第 1,2 和 3 行的图像完成下载时),第 9、10 和 11 单元格上的图像将更改为属于 1,2 和 3 的图像。 我不知道当我重复使用单元格时是否有办法阻止图像下载,或者类似的东西。 谢谢你,对不起我的英语!

【问题讨论】:

  • 是 cell.userImage 还是只是 userImage?
  • loadFromDictionary 是 cell.userDetailsView 的一个方法,是自定义的 UserDetailsTableViewCell 里面的自定义视图。在那个 loadFromDictionary 方法里面只有 userImage。
  • 啊哈我现在明白了,我也很高兴你找到了解决方案。

标签: ios uitableview sdwebimage


【解决方案1】:

如果您在表格上设置了 UITableViewDelegate,则可以使用委托方法:

- tableView:didEndDisplayingCell:forRowAtIndexPath:

当您的单元格滚出屏幕时将图像设置为 NULL(或默认值)。

由于您使用的是 SDWebImage,因此取消它可以像单元格图像视图上的 "cancelCurrentImageLoad" 一样简单。

【讨论】:

  • 谢谢,我在每次重复使用单元格时都调用loadFromDictionary之前添加了cancelCurrentImageLoad
  • 我也在使用那个库,但到目前为止我没有任何问题。当我在线程中使用调度和设置图像时发生了这种问题,但是非常感谢你的建议,这真的是一个很好的提示。我真的向遇到同样问题的任何人推荐这个答案!
  • 但是如果单元格确实显示并且仍然没有完成加载图像本身的情况!为什么取消加载图片呢?你怎么能处理这种情况?谢谢!
【解决方案2】:

覆盖单元类中的prepareForReuse 方法并取消那里的所有加载。不要忘记拨打super

【讨论】:

    【解决方案3】:

    上面的答案示例。斯威夫特 3

    func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        (cell as! UITableViewCell).imageView.image = nil
        (cell as! UITableViewCell).imageView.sd_cancelCurrentImageLoad()
    }
    

    【讨论】:

      【解决方案4】:

      我得到了接受答案的空白图像,并且考虑到我正在加载的图像很小,我想让图像缓存在后台而不是取消加载。

      1. 在您关闭之前在堆栈上推送一个唯一 ID,并在您的关闭完成时检查它
      2. prepareForReuse

      像这样:

      func updateArtistImage(url: URL) {
              let _eventId = self.event?.id
              SDWebImageManager.shared().loadImage(with: url, options: [], progress: nil) { (image, data, error, cacheType, finished, url) in
                  if self.event!.id == _eventId {
                      if error == nil {
                          self.artistImageView.image = image
                      } else {
                          self.artistImageView.image = UIImage(named: "error_image")
                      }
                  }
              }
          }
      

      还有这个:

      override func prepareForReuse() {
          super.prepareForReuse()
          self.artistImageView.image = nil
      }
      

      【讨论】:

        【解决方案5】:

        只需调用sd_cancelCurrentImageLoad 并在调用sd_setImageWithURL 之前设置[imageView setImage:nil]

        [imageView sd_cancelCurrentImageLoad]; 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-31
          • 1970-01-01
          相关资源
          最近更新 更多