我有一个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
}
}
日志记录表明集合视图在视图加载时尝试立即获取所有照片资源的动态大小。我错过了什么吗?