我有一个缓存相机胶卷中所有照片的实现UICollectionViewController
。PHCachingImageManager
这适用于正常的收藏视图布局,即使有大约 2000 张照片。
但是,如果我实现UICollectionViewDelegateFlowLayout
,应用程序在尝试获取每个图像资产项的图像大小时会崩溃。
//MARK: - UICollectionViewDataSource
extension ImportPhotoViewController: UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.fetchedPhotoAssets?.count!
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let asset = self.fetchedPhotoAssets![indexPath.item]
//dequeue cell
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! LibraryPhotoCell
cell.representedAssetIdentifier = asset.localIdentifier
cell.backgroundColor = UIColor.whiteColor()
//Request an image for the asset from the PHCachingImageManager
self.imageManager?.requestImageForAsset(asset as! PHAsset,
targetSize: ImportPhotoViewController.AssetGridThumbnailSize!,
contentMode: PHImageContentMode.AspectFit,
options: nil,
resultHandler: { (image, _) in
if cell.representedAssetIdentifier == asset.localIdentifier {
cell.imageView.image = image
}
})
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
//select photo
}
}
//MARK: - UICollectionViewDelegateFlowLayout
private var imageManager: PHCachingImageManager?
extension ImportPhotoViewController: UICollectionViewDelegateFlowLayout {
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let asset = self.fetchedPhotoAssets![indexPath.item]
var size = ImportPhotoViewController.AssetGridThumbnailSize
self.imageManager?.requestImageForAsset(asset as! PHAsset,
targetSize: ImportPhotoViewController.AssetGridThumbnailSize!,
contentMode: .AspectFill,
options: nil,
resultHandler: { (image, _) in
size = image?.size
size!.width += 10
size!.height += 10
})
return size!
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
return sectionInsets
}
}
UI滚动时触发缓存功能
private func updateCachedAssets() {
let isViewVisible = self.isViewLoaded() && ((self.collectionView as UICollectionView).window != nil)
if !isViewVisible { return }
//The preheat window is twice the height of the visible rect
var preheatRect = self.collectionView.bounds
preheatRect = CGRectInset(preheatRect, 0, -0.5 * CGRectGetHeight(preheatRect))
//Check if the collection view is showing an area that is significantly
//different to the last preheat area.
let delta = abs(CGRectGetMidY(preheatRect) - CGRectGetMidY(previousPreheatRect))
if (delta > CGRectGetHeight(self.collectionView.bounds) / 3) {
QL1("updateCachedAssets")
let addedIndexPaths = [] as NSMutableArray
let removedIndexPaths = [] as NSMutableArray
computeDifferenceBetweenRect(previousPreheatRect, newRect: preheatRect,
removedHandler: { (removedRect) in
let indexPaths = self.collectionView.indexPathsForElementsInRect(removedRect)
removedIndexPaths.addObjectsFromArray(indexPaths as [AnyObject])
}, addedHandler: { (addedRect) in
let indexPaths = self.collectionView.indexPathsForElementsInRect(addedRect)
addedIndexPaths.addObjectsFromArray(indexPaths as [AnyObject])
})
let assetsToStartCaching = self.assetsAtIndexPaths(addedIndexPaths)
let assetsToStopCaching = self.assetsAtIndexPaths(removedIndexPaths)
//update the assets the PHCachingImageManager is caching
imageManager?.startCachingImagesForAssets(assetsToStartCaching as! [PHAsset], targetSize: ImportPhotoViewController.AssetGridThumbnailSize!, contentMode: .AspectFit, options: nil)
imageManager?.stopCachingImagesForAssets(assetsToStopCaching as! [PHAsset], targetSize: ImportPhotoViewController.AssetGridThumbnailSize!, contentMode: .AspectFit, options: nil)
//store the preheat rect to compare against in the future
self.previousPreheatRect = preheatRect
}
}
日志记录表明集合视图试图在视图加载时立即获取所有照片资产的动态大小。我错过了什么吗?