我正在尝试将图像加载到表中,但我仍然在闪烁。图像正在加载,但在滚动时,在下一个缩略图图像加载之前会出现短暂的闪烁。是的,知道Apple有一个例子和各种框架,但这是超级简单的代码,只是在下载图像加载之前该死的闪烁。其他一切都很好。 谢谢!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"customCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[CustomCell class]]) {
cell = (CustomCell *)currentObject;
break;
}
}
}
NSString *myUrl = [[items objectAtIndex:indexPath.row] objectForKey:@"myUrl"];
NSURL *url = [NSURL URLWithString:url];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^{
UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
dispatch_sync(dispatch_get_main_queue(), ^{
[[cell imageView] setImage:image];
[cell setNeedsLayout];
});
});
return cell;
}
答案 0 :(得分:1)
您正在使用UITableView
的重复使用机制。这意味着您可以从dequeueReusableCellWithIdentifier
获取已有图像集的单元格。因此,首先您需要使用[[cell imageView] setImage:nil]
删除图像。然后在调度块内部,您无法确定该单元格是否仍在屏幕上。您需要检查索引路径是否仍然相同,否则您将图像设置为错误的单元格:
dispatch_async(queue, ^{
UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
dispatch_sync(dispatch_get_main_queue(), ^{
if ([[tableView indexPathForCell:cell] compare:indexPath] == NSOrderedSame) {
[[cell imageView] setImage:image];
[cell setNeedsLayout];
}
// alternative:
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if (cell)
cell.imageView.image = image;
});
});
我建议使用NSOperation
子类来加载远程图像而不是使用dataWithContentsOfURL
- 然后您也可以在单元格离开时取消图像加载。
还要考虑使用图像缓存以获得更好的性能。
答案 1 :(得分:0)
我有一个类似的问题,您需要检查以查看图像是否已加载。您当前的代码只是加载图像,但如果单元格已经有图像怎么办?每次用户滚动表时,您都不希望执行此任务。
查看我提出的问题。