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

时间:2015-05-27 03:23:16

标签: ios objective-c image uicollectionview uicollectionviewcell

我正在尝试将文档目录中的图像加载到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;
}

3 个答案:

答案 0 :(得分:3)

你必须放置默认/占位符图像以防止这种情况..

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

答案 1 :(得分:1)

我遇到过同样的问题。用下面的方法解决了它。

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

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

希望这能解决您的问题。

答案 2 :(得分:1)

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