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;

}

我不知道出了什么问题,但我认为是因为我解析单元格中的图像并且速度不够快,所以它一次又一次地开始。你能告诉我如何解决这个问题吗

4

2 回答 2

4

我相信,高级别的答案是,当您滚动时,您会在完成将图像放入其中之前重用单元格。无论如何,当我在代码中看到它时,这就是它的意思。

我不使用 SDWebImage 并且我不确切知道 setImageWithURL 变体是什么,但是 github 网页有一个使用方法,说你可以给它一个完成块以在图像获取完成时执行(成功或失败)。因此,您需要检查,当您最终获得图像但在将其放入 UITableViewCell 之前,该单元格是否仍分配给与您开始获取图像时相同的 indexPath。由于 setImageWithURL 似乎总是设置图像,因此您必须放置一个临时 UIImageView 而不是直接在单元格中。我查看的文档有一个带有 placeHolderImage: 和 completed: 的方法调用:使用它你会做类似的事情(代码未经过编译器检查):

// 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;
    }
}];
于 2013-03-31T20:08:49.377 回答
0

更改单元格标识符

static NSString *CellIdentifier = @"Cell"; 

NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%i",indexPath.row];
于 2013-03-31T20:53:17.630 回答