0

我有一个缓存相机胶卷中所有照片的实现UICollectionViewControllerPHCachingImageManager

这适用于正常的收藏视图布局,即使有大约 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
    }
}

日志记录表明集合视图试图在视图加载时立即获取所有照片资产的动态大小。我错过了什么吗?

4

0 回答 0