如何使用PHCachingImageManager

我知道已经存在这个问题了,但我不认为给定的答案是令人满意/完整的: IOS Photos应用程序如何在一个屏幕上显示数百张照片?

我想要实现的目标

我想要像whatsapp(iOS)中的图像选择(见截图)。 打开相机时,还有一个水平滑块,您可以在其中查看图库中的所有图像。

whatsapp截图

我尝试了什么

现在我的appDelegate中有以下代码:

let options = PHFetchOptions() options.sortDescriptors = [ NSSortDescriptor(key: "creationDate", ascending: true) ] if let results = PHAsset.fetchAssetsWithMediaType(.Image, options: options) { results.enumerateObjectsUsingBlock { (object, idx, _) in if let asset = object as? PHAsset { Variables.assets.append(asset) } } println(Variables.assets.count) Variables.imageManager.startCachingImagesForAssets(Variables.assets, targetSize: CGSizeMake(viewWidth, viewWidth), contentMode: .AspectFill, options: self.requestOptions) } 

后来我在UITableViewController中加载图像并在滚动时调用以下函数:

 func fetchPhotoAtIndex(index : Int) { let asset = Variables.assets[Variables.assets.count - 1 - index] as PHAsset Variables.imageManager.requestImageForAsset(asset, targetSize: CGSizeMake(self.viewWidth, self.viewWidth), contentMode: .AspectFill, options: self.requestOptions, resultHandler: { (image, _) in println("\(asset.localIdentifier) \(asset.creationDate) ") [...] self.tableView.reloadData() }) } 

这很好,但我遇到的问题是,在每个应用程序启动时,我的所有资产都会被缓存。 这是解决我问题的正确方法吗? 如何像whatsapp一样实时显示图库照片?

参考此照片框架示例在此项目中,您应该查看文件AAPLAssetGridViewController.m以及它如何根据您的滚动位置处理缓存。

  - (void)updateCachedAssets { BOOL isViewVisible = [self isViewLoaded] && [[self view] window] != nil; if (!isViewVisible) { return; } // The preheat window is twice the height of the visible rect CGRect preheatRect = self.collectionView.bounds; preheatRect = CGRectInset(preheatRect, 0.0f, -0.5f * CGRectGetHeight(preheatRect)); // If scrolled by a "reasonable" amount... CGFloat delta = ABS(CGRectGetMidY(preheatRect) - CGRectGetMidY(self.previousPreheatRect)); if (delta > CGRectGetHeight(self.collectionView.bounds) / 3.0f) { // Compute the assets to start caching and to stop caching. NSMutableArray *addedIndexPaths = [NSMutableArray array]; NSMutableArray *removedIndexPaths = [NSMutableArray array]; [self computeDifferenceBetweenRect:self.previousPreheatRect andRect:preheatRect removedHandler:^(CGRect removedRect) { NSArray *indexPaths = [self.collectionView aapl_indexPathsForElementsInRect:removedRect]; [removedIndexPaths addObjectsFromArray:indexPaths]; } addedHandler:^(CGRect addedRect) { NSArray *indexPaths = [self.collectionView aapl_indexPathsForElementsInRect:addedRect]; [addedIndexPaths addObjectsFromArray:indexPaths]; }]; NSArray *assetsToStartCaching = [self assetsAtIndexPaths:addedIndexPaths]; NSArray *assetsToStopCaching = [self assetsAtIndexPaths:removedIndexPaths]; [self.imageManager startCachingImagesForAssets:assetsToStartCaching targetSize:AssetGridThumbnailSize contentMode:PHImageContentModeAspectFill options:nil]; [self.imageManager stopCachingImagesForAssets:assetsToStopCaching targetSize:AssetGridThumbnailSize contentMode:PHImageContentModeAspectFill options:nil]; self.previousPreheatRect = preheatRect; } } //In your case this computeDifference method changes to handle horizontal scrolling - (void)computeDifferenceBetweenRect:(CGRect)oldRect andRect:(CGRect)newRect removedHandler:(void (^)(CGRect removedRect))removedHandler addedHandler:(void (^)(CGRect addedRect))addedHandler { if (CGRectIntersectsRect(newRect, oldRect)) { CGFloat oldMaxY = CGRectGetMaxY(oldRect); CGFloat oldMinY = CGRectGetMinY(oldRect); CGFloat newMaxY = CGRectGetMaxY(newRect); CGFloat newMinY = CGRectGetMinY(newRect); if (newMaxY > oldMaxY) { CGRect rectToAdd = CGRectMake(newRect.origin.x, oldMaxY, newRect.size.width, (newMaxY - oldMaxY)); addedHandler(rectToAdd); } if (oldMinY > newMinY) { CGRect rectToAdd = CGRectMake(newRect.origin.x, newMinY, newRect.size.width, (oldMinY - newMinY)); addedHandler(rectToAdd); } if (newMaxY < oldMaxY) { CGRect rectToRemove = CGRectMake(newRect.origin.x, newMaxY, newRect.size.width, (oldMaxY - newMaxY)); removedHandler(rectToRemove); } if (oldMinY < newMinY) { CGRect rectToRemove = CGRectMake(newRect.origin.x, oldMinY, newRect.size.width, (newMinY - oldMinY)); removedHandler(rectToRemove); } } else { addedHandler(newRect); removedHandler(oldRect); } } - (NSArray *)assetsAtIndexPaths:(NSArray *)indexPaths { if (indexPaths.count == 0) { return nil; } NSMutableArray *assets = [NSMutableArray arrayWithCapacity:indexPaths.count]; for (NSIndexPath *indexPath in indexPaths) { PHAsset *asset = self.assetsFetchResults[indexPath.item]; [assets addObject:asset]; } return assets; } 

图像缓存管理器使用所需大小的资源进行加热,然后您可以从图像缓存管理器本身检索它们。

希望它能帮到你。

Interesting Posts