我使用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;
}
我不知道出了什么问题,但我认为是因为我在单元格中解析图像并且速度不够快所以它会一次又一次地启动。你能告诉我如何解决这个问题
答案 0 :(得分: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;
}
}];
答案 1 :(得分:0)
从
更改单元格标识符static NSString *CellIdentifier = @"Cell";
到
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%i",indexPath.row];