2013-03-31 35 views
1

我使用SDWebImage加載和顯示TableView中的異步圖像。但有時當我快速上下滾動時,它會混合所有圖像並將其顯示在其他行中。這是我的cellForRowAtIndexPath:表視圖混合圖像

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

    static NSString *CellIdentifier = @"Cell"; 

    CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 

     cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 

    } 

// Configure the cell. 

MWFeedItem *item = [itemsToDisplay objectAtIndex:indexPath.row]; 

if (item) { 


     // Parse out Image URL for cell 

     if (cell.imageView.image == nil) { 

     NSError *error = NULL; 

     NSRegularExpression *regexImage = [NSRegularExpression regularExpressionWithPattern:@"(<img\\s[\\s\\S]*?src\\s*?=\\s*?['\"](.*?)['\"][\\s\\S]*?>)+?" 

                       options:NSRegularExpressionCaseInsensitive 

                       error:&error]; 
     [regexImage enumerateMatchesInString:item.content 

           options:0 

            range:NSMakeRange(0, [item.content length]) 

          usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { 



           NSString *src = [item.content substringWithRange:[result rangeAtIndex:2]]; 

           NSLog(@"img src: %@", src); 

           [cell.imageView setImageWithURL:[NSURL URLWithString:src]]; 

          }];} 



     if (cell.imageView.image == nil) { 

      cell.imageView.image = [UIImage imageNamed:@"video.png"]; 

} 

    return cell; 

} 

我不知道什麼是錯的,但我認爲它是因爲我在解析細胞的圖像,所以它一次又一次啓動它是不夠快。你能告訴我如何解決這個問題嗎?

回答

1

更改小區標識從

static NSString *CellIdentifier = @"Cell"; 

NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%i",indexPath.row]; 
+0

它的作品,非常感謝你! –

+0

很高興能幫到:) –

+0

@ Supporter_04,這可能有效,但它在我看來好像爲每個數據項創建了一個新的單元格,因此您不會獲得任何單元格的重用。這打破了UITableView的內存效率。查理的答案可能很難實現(你需要正確理解SDWebImage的細節),但是它遵守細胞重用的原則。 – foundry

4

我相信,高級別的回答是,當你滾動時,你在完成把圖像放入它們之前重複使用單元格。無論如何,我在我的代碼中看到這個意思就是這個意思。

我不使用SDWebImage,我不確切知道setImageWithURL變體是什麼,但是github網頁有一個使用方法,說你可以給它一個完成塊,以便在完成圖像抓取時執行(成功或失敗)。 所以你需要檢查,當你最終有圖像,但在你把它放入UITableViewCell之前,單元格仍然被分配到與開始獲取圖像時相同的indexPath。由於setImageWithURL似乎總是設置圖像,因此您必須放置一個臨時UIImageView,而不是直接放入單元格中。我看了該文檔在曾與兩個placeHolderImage方法調用:完成:使用你會做這樣的事情(代碼不檢查編譯):

// before you go off to get the image, save the indexPath of the cell 
NSIndexPath *originalIndexPath = indexPath; 
UIImageView *tempImageView; 
[tempImageView setImageWithURL:[NSURL URLWithString : [NSURL URLWithString:src]] 
      placeholderImage:[UIImage imageNamed:@"placeholder.png"] 
        completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) { 
    // completion block 
    // You probably want to check that it really succeeded, but if it did 
    // Now you have an image in the image parameter and probably in tempImageView. 
    // Check to see if the cell is still at the original indexPath 
    // If so, put the image in. 
    // If not, the row was scrolled out of sight and the cell has been reused 
    // so just drop the image on the floor -- it is no longer useful 
    NSIndexPath *currentIndexPath = [self.tableview indexPathForCell:cell] 
    if ([currentIndexPath isEqual originalIndexPath]) { 
     cell.imageView.image = image; 
     // or perhaps: cell.imageView.image = tempImageView.image; 
    } 
}]; 
+0

setImageWithURL是由SDWebImage分配的方法。你能告訴我在哪裏把這段代碼放在上面嗎? –

+0

好吧,我看了(簡要)SDWebImage並編輯了我的答案。您需要自己將圖像放入單元格中,但只有當單元格未被重用時才需要。如何在tableview中使用這個簡單的例子就是*錯誤*,因爲它確實遇到了你遇到的問題。每當你用tableviews做異步圖像的東西時,你需要做這種檢查來查看單元格是否仍具有相同的標識 - 即滾動並未導致單元被釋放並可能被重用。 –

+0

感謝您爲此付出的努力。我在'if([currentIndexPath isEqual originalIndexPath]')行中得到一個錯誤'它說在originalIndexPath –