将图像从资源库加载到UICollectionView

时间:2014-09-16 07:33:26

标签: ios objective-c uiimageview uicollectionview

我正在使用 ELCImagePicker https://github.com/B-Sides/ELCImagePickerController从手机库中选择我的图片。 ELC有两个选项可供选择,第一个是UIImage本身(当我选择5个以上的图像时,由于内存崩溃,我不想要它)。第二个是图像的资产位置,这对内存有好处,虽然我的问题是在集合视图上显示图像。

所以我有这段代码可以正常运行并显示图像,但是当我在集合视图中向上和向下滚动时,它会稍微滞后。我认为这是因为每次它想要加载一个单元时,它必须通过一个块并且它是异步的。我试图找到一种方法来消除滞后并使其平滑滚动。

任何帮助将不胜感激。 :)

 ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

 [library assetForURL:_chosenImages[indexPath.row] resultBlock:^(ALAsset *asset) {

    UIImage *image = [UIImage imageWithCGImage:asset.thumbnail];
  // I believe the problem is here..
    [myCell.imageView setImage:image];
} failureBlock:^(NSError *error) {
    NSLog(@"An error occurred while loading image: %@", error.description);
}];

2 个答案:

答案 0 :(得分:1)

- (void)selectedAssets:(NSArray *)assets中的ELCImagePickerController.m方法中,您将能够看到此行

ALAsset *asset = elcasset.asset;

在此行之后,会创建一个字典,然后添加到returnArray。跳过此字典创建部分。直接将资产添加到returnArray。将for方法更改为:

for(ELCAsset *elcasset in assets) {
    ALAsset *asset = elcasset.asset;
    [returnArray addObject:asset];  
}

玩得开心。

<强> *** *** EDIT 另外,请创建一个单身人士,以维持AssetLibraryELCAlbumPickerController的生命。

答案 1 :(得分:0)

首先,ALAssetsLibrary并不保证在主线程上调用结果块。你应该在后台线程上做昂贵的事情(生成UIImage),任何UI工作都应该在主线程上完成。所以你需要先解决这个问题:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    UIImage *image = [UIImage imageWithCGImage:asset.thumbnail];

    dispatch_async(dispatch_get_main_queue(), ^{
        [myCell.imageView setImage:image];
    });
});

其次,当您最终到达myCell时,此单元格不再保证具有相同的内容。这是因为在滚动期间重复使用单元格。所以你需要得到正确的细胞。

一种常见方法是使用indexPath

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    UIImage *image = [UIImage imageWithCGImage:asset.thumbnail];

    dispatch_async(dispatch_get_main_queue(), ^{
        MyUICollectionViewCellSubclass *correctCell = (MyUICollectionViewCellSubclass *)[self.collectionView cellForItemAtIndexPath:indexPath];
        [correctCell.imageView setImage:image];
    });
});

但是,只有在保证索引路径不会改变的情况下才能使用,这取决于您的用例,可能会也可能不会。例如,如果用户可以插入或删除项目,则您需要采用不同的(但类似的)方法。

最后,请确保在重复使用单元格时nil imageView image imageWithCGImage:,因此当单元格滚动时,您不会显示旧图像。 )


此外,我使用资产库已经有一段时间了,但我认为你不应该使用imageWithCGImage:scale:orientation:而是使用{{1}}。我相信您目前使用的方法在Retina设备上看起来会模糊,并且可能会导致方向错误。