在uitableviewcell中异步加载图像

时间:2012-12-31 17:05:49

标签: ios objective-c uitableview

我正在尝试异步加载UITableVIew中的图片。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

UITableViewCell *cell = nil;
NSString *cellIndetify = [NSString stringWithFormat:@"cell%d",tableView.tag -TABLEVIEWTAG];

cell = [tableView dequeueReusableCellWithIdentifier:cellIndetify];
IndexPath *_indextPath = [IndexPath initWithRow:indexPath.row  withColumn:tableView.tag - TABLEVIEWTAG];
if (cell == nil) {

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndetify];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.contentView.backgroundColor = [UIColor blackColor];
// here I init cell image view
        UIView *cellSub =  [self.waterFlowViewDatasource waterFlowView:self cellForRowAtIndexPath:_indextPath];

    cellSub.backgroundColor = [UIColor blackColor];
    [cell.contentView addSubview:cellSub];
    cellSub.tag = CELLSUBVIEWTAG;

}
// fill image info 
    [self.waterFlowViewDatasource waterFlowView:self fillDataIntoCellSubview:[cell viewWithTag:CELLSUBVIEWTAG] withIndexPath:_indextPath];


CGFloat cellHeight = [self.waterFlowViewDelegate waterFlowView:self heightForRowAtIndexPath:_indextPath];

CGRect cellRect = CGRectMake(0, 0, _cellWidth, cellHeight);
[[cell viewWithTag:CELLSUBVIEWTAG] setFrame:cellRect];


[self.waterFlowViewDatasource waterFlowView:self relayoutCellSubview:[cell viewWithTag:CELLSUBVIEWTAG] withIndexPath:_indextPath];

return cell;
}

ImageView类我初始化:

(id)initWithIdentifier:(NSString *)indentifier
{
    if(self = [super initWithIdentifier:indentifier])
    {
        self.backgroundColor = [UIColor blackColor];

        if (!self.imageView) {
            _imageView = [[UIImageView alloc] init];
            self.imageView.backgroundColor = IMAGEVIEWBG;
            [self addSubview:self.imageView];

            self.imageView.layer.borderWidth = 1;
            self.imageView.layer.borderColor = [[UIColor colorWithRed:0.85 green:0.85 blue:0.85 alpha:1.0] CGColor];
        }
        ......some others controllers
}

-(void)setImageWithURL:(NSURL *)imageUrl{


    UIImage *cachedImage = [[SDImageCache sharedImageCache] imageFromKey:[imageUrl absoluteString]];
    if (cachedImage) {
        self.imageView.image = cachedImage;
    }else{
        SDWebImageManager *manager = [SDWebImageManager sharedManager];
            [manager downloadWithURL:imageUrl delegate:self options:SDWebImageCacheMemoryOnly userInfo:[[NSDictionary alloc] initWithObjectsAndKeys:[imageUrl absoluteString], @"image_url", [NSValue valueWithBytes:&imageSize objCType:@encode(CGSize)], @"image_size", [NSNumber numberWithInt:arrIndex], @"imageview_index", nil]];
            _imageView.image = [UIImage imageNamed:@"album_detail_placeholder.png"];
}
.....
.....

- (void)imageDecoder:(SDWebImageDecoder *)decoder didFinishDecodingImage:(UIImage *)image userInfo:(NSDictionary *)userInfo {

       imageView.image = image
}

如您所见,我使用了SDWebImageManager,但这似乎不是问题。

当上传到下一页时,在下一页的图像加载之前,如果我回滚到上一页的加载图像,图像将被另一张图像覆盖(应显示在最新页面,而不是当前页面。 ..)(例如,在第一页,我有一个图像,在这个图像中有猫,然后我向下滚动直到请求下一页,并在获得所有下一页图像的URL后,启动异步线程下载图像,在下载最新图像之前,滚动回顶部,可能是第一页。过了一段时间,一些图像下载后,它们应该显示在那里的单元格中,但现在图像将覆盖当前页面图像,也许猫图像现在有一只狗它上面的图像)我该怎么办?

1 个答案:

答案 0 :(得分:1)

当一行在屏幕外滚动时,表格视图会将该行的单元格重新用于已在屏幕上滚动的另一行。

问题在于您使用ImageView作为后台加载程序的委托,而ImageView与单元格相关联,而不是与行相关联。当后台加载程序完成加载图像时,该单元格可能已被重用于另一行。

您需要使表视图的数据源成为背景图像加载器的委托。它应该在调用userInfo时将行的索引路径放入downloadWithURL:delegate:options:userInfo:字典中。当下载程序将imageDecoder:didFinishDecodingImage:userInfo:发送到数据源时,数据源应该从userInfo中获取索引路径并使用它来向表视图询问当前显示该行的单元格(通过发送{{ 1}}到表视图)。