将文档目录中的图像异步加载到 UICollectionView

Asynchronously load images from document directory into UICollectionView

我正在尝试将文档目录中的图像加载到 UICollectionView。它的工作原理:流畅,快速....(笑)。但我遇到一个问题:当我调用 [collectionView reloadData] 时,图像闪烁(一次)。这是我的代码:

- (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;
}

我遇到了同样的闪烁图像的问题并使用以下方法解决了它。

应用相同的延迟加载概念。就像在显示之前创建一个字典对象来存储所有图像一样,在从文档目录获取图像之前检查图像是否在字典中,如果它在那里然后使用该图像来显示它。

如果字典中没有图像,则进行数据库操作。

希望这能解决您的问题。

问题是您正在启动图像视图的异步更新,但如果重复使用该单元格,您将在那里看到旧图像。因此,在您 dispatch_async 检索图像的过程之前,请确保先将 cell.imageView.image 设置为 nil。因此,在启动正确图像的异步检索之前,请确保您从未在单元格中看到先前的图像。

您必须放置 default/placeholder 图片以防止出现这种情况..

    // 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..
        });
    });