2012-12-31 125 views
1

我想異步加載圖像在UITableVIew在uitableviewcell異步加載圖像

- (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

我INIT:

(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

當一行在屏幕外滾動時,表視圖重用該行的單元格作爲屏幕上滾動的另一行。

問題是,您正在使用ImageView作爲背景加載器的代理,而ImageView與單元格關聯,而不是行。當背景加載器完成加載圖像時,該單元可能已被重新用於另一行。

您需要將表視圖的數據源作爲背景圖像加載器的代理。當它調用downloadWithURL:delegate:options:userInfo:時,它應該將該行的索引路徑放入userInfo字典中。當下載器將imageDecoder:didFinishDecodingImage:userInfo:發送到數據源時,數據源應該從userInfo中獲取索引路徑,並使用它向表格視圖詢問當前顯示該行的單元(通過將cellForRowAtIndexPath:發送到表視圖)。

+0

是的,是的,是的,你完全正確@rob !!!!!但我不太明白「用它來查詢當前顯示該行的單元格的表視圖(通過發送cellForRowAtIndexPath:到表視圖)」。你能告訴我一些示例代碼嗎? –

+0

嘿@rob我明白了!哦,你幫了很多,感謝哥們! –