IOS Photos应用程序如何在一个屏幕上显示数百张照片?

时间:2014-10-10 10:57:09

标签: ios objective-c uicollectionview

我正在开发一个依赖于从多个来源在屏幕上显示大量照片的应用程序。

我想知道苹果如何在他们的照片应用程序中制作“照片拼贴”视图?有这么多的照片,在我看来应用程序应该提供内存警告,一次显示较少的照片(即使我加载“缩略图大小”的照片),但我可以看到它可以在我缩放时在一个屏幕上显示数百张照片出。

我能想到的一种方式是这些视图不是单独的照片,而是实时从照片生成的单个“平铺”图像,因此应用程序一次只显示2-3张照片。但是这仍然需要大量的CPU功率和时间来快速生成。我可以立即放大或缩小。

我想在我的应用程序中实现类似的功能,任何有关如何实现这一目标的指示都会很棒。

感谢您的回答。

IOS 7 Photos.app

2 个答案:

答案 0 :(得分:10)

我做了一些研究,发现IOS8有一个很棒的新框架叫做“照片框架”

此框架可让您轻松缓存图像,调用具有预定义大小的缩略图图像并加载项目。 (旧的ALAsset库只有一个“缩略图”大小,你必须调整自己的大小。)

在我的测试中,屏幕上充满了20x20张照片(我的手机屏幕内容为384张图片),app只需要10mb的内存,滚动时几乎没有闪烁。通过优化单元重新加载imo可以实现平滑滚动。

这是我用于将图像加载到20x20项目大小的uicollectionview中的代码:

@import Photos;
@interface MainViewController ()

@property (strong) PHFetchResult *assetsFetchResults;
@property (strong) PHCachingImageManager* imageManager;

@end

在viewDidLoad上:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.imageManager = [[PHCachingImageManager alloc] init];

    CGFloat scale = [UIScreen mainScreen].scale;
    CGSize cellSize = ((UICollectionViewFlowLayout *)self.collectionViewLayout).itemSize;
    AssetGridThumbnailSize = CGSizeMake(cellSize.width * scale, cellSize.height * scale);

    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
    self.assetsFetchResults = [PHAsset fetchAssetsWithOptions:nil];
    // Do any additional setup after loading the view.
}

和集合视图数据源方法:

#pragma mark <UICollectionViewDataSource>

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}


- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.assetsFetchResults.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];

    [self.imageManager requestImageForAsset:self.assetsFetchResults[indexPath.item] 
                                 targetSize:CGSizeMake(20, 20) 
                                contentMode:PHImageContentModeAspectFill 
                                    options:nil resultHandler:^(UIImage *result, NSDictionary* info){

                                        UIImageView* imgView = (UIImageView*)[cell.contentView viewWithTag:999];
                                        if(!imgView) {
                                            imgView = [[UIImageView alloc] initWithFrame:[cell.contentView bounds]];
                                            imgView.tag = 999;
                                            [cell.contentView addSubview:imgView];
                                        }
                                        imgView.image = result;
                                    }];
    // Configure the cell

    return cell;
}

多数民众赞成!

答案 1 :(得分:1)

使用PHCachingImageManager的Apple示例要好得多,因为它还使用预热文本以便缓存正确的资源。请查看https://developer.apple.com/library/ios/samplecode/UsingPhotosFramework/Listings/SamplePhotosApp_AAPLAssetGridViewController_m.html 抱歉格式不正确,希望有所帮助