从文档目录异步加载图像到UICollectionView
问题描述:
我想从文档目录加载图像到UICollectionView
。它的工作原理:平稳,快速....(大声笑)。但我得到一个问题:当我打电话[collectionView reloadData]
,图像闪烁(一次)。这里是我的代码:从文档目录异步加载图像到UICollectionView
- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView_ cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = NSStringFromClass([AFMyRecentCollectionViewCell class]);
AFMyRecentCollectionViewCell *cell = (AFMyRecentCollectionViewCell*)[collectionView_ dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
AFMyRecentObject *recent = [[AFRecentManager sharedInstance].arrayRecent objectAtIndex:indexPath.row];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
UIImage *image;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filePath = [self databasePathWithPathComponent:[NSString stringWithFormat:@"%@.jpg", recent.id_film]];
if ([fileManager fileExistsAtPath:filePath] == YES) {
image = [UIImage imageWithContentsOfFile:filePath];
}
dispatch_async(dispatch_get_main_queue(), ^{
if (image) {
cell.imageView.image = image;
} else {
cell.imageView.image = [UIImage imageNamed:@"loadding.png"];
}
});
});
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
return cell;
}
- (NSString *)databasePathWithPathComponent:(NSString*)pathComponent {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex: 0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:pathComponent];
return path;
}
答
我面临flickring &解决它使用以下方法图像的同样的问题。
应用相同的延迟加载概念。像创建一个字典对象来存储显示之前的所有图像,在从文档目录获取图像之前,检查字典中是否存在图像,如果它存在,则使用该图像来显示它。
如果图像不在字典中,那么做数据库操作。
希望这可以解决您的问题。
答
问题是,您正在启动图像视图的异步更新,但是如果单元格被重用,您将在那里看到旧图像。因此,在您检索图像之前dispatch_async
,请确保您先将cell.imageView.image
设置为nil
。因此,请确保在启动正确图像的异步检索之前,您不会在单元格中看到之前的图像。
答
你必须放置和默认/图像占位符,以防止..
// this prevents the flicker/blinks
cell.imageView.image = nil; // if you dont have any image as placeholder
//since you have
cell.imageView.image = [UIImage imageNamed:@"loadding.png"]; // this i assume your placeholder image?
dispatch_async(queue, ^{
//your codes..
dispatch_async(dispatch_get_main_queue(), ^{
// your codes..
});
});
顺便说一句,你在技术上应该确保了'cell'还没有被重新用于另一个'NSIndexPath' 'UIImage'被实例化的时间。很可能,因为你从本地存储中检索,这不太可能是个问题,但是如果你要发起任何网络请求,那么在蜂窝网络上快速滚动时突然变成一个非常实际的问题。因此,要非常小心地使用上述模式,除非您确信在异步更新过程中单元格不能重新使用。 – Rob