带有PhotoFramework资产的Swift UICollectionView FlowLayout

时间:2016-07-25 11:06:49

标签: ios swift collectionview phphotolibrary

我有一个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
    }
}

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

0 个答案:

没有答案