照片框架和可重复使用的UICollectionViewCell

时间:2016-01-29 16:03:49

标签: ios swift photosframework

我有一个UICollectionView来显示设备相册中带有Photos框架的照片。照片是正确显示的,但如果我快速滚动(就像你在屏幕顶部的磁带上转到集合视图的顶部),我有一些照片不是好的indexPath。我只需要滚动一下就可以将坏照片从屏幕上取出来,一切都会恢复原状。

我通过取消当前请求在prepareForReuse期间清理单元格。

我认为PHImageManager的异步请求存在问题,但我不知道如何避免此问题。

这里有一些代码:

查看控制器

extension AlbumDetailViewController : UICollectionViewDataSource {
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return photoList.count
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("PhotoCell", forIndexPath: indexPath) as! PhotoCollectionCell

        cell.setImage(photoList.objectAtIndex(indexPath.row) as! PHAsset)

        return cell
    }
}

自定义CollectionViewCell

class PhotoCollectionCell: UICollectionViewCell {

    @IBOutlet weak var imageView: UIImageView!

    var requestId: PHImageRequestID!
    let manager = PHImageManager.defaultManager()

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func prepareForReuse() {
        self.imageView.image = nil

        manager.cancelImageRequest(self.requestId)
    }

    func setImage(asset: PHAsset) {

        let option = PHImageRequestOptions()

        option.resizeMode = .Fast
        option.deliveryMode = .HighQualityFormat

        self.requestId = manager.requestImageForAsset(asset, targetSize: CGSize(width: self.frame.size.width * UIScreen.mainScreen().scale, height: self.frame.size.height * UIScreen.mainScreen().scale), contentMode: PHImageContentMode.Default, options: option, resultHandler: {(result, info)->Void in
            self.imageView.image = result
        })
    }
}

谢谢

1 个答案:

答案 0 :(得分:1)

在调用requestImageForAsset方法之前,将cell.tag设置为indexPath.item,在回调中获取图像之后,检查indexPath.item和cell.tag,如果匹配则执行该操作 self.imageView.image =结果。例如

        cell.tag = indexPath.item

        if let asset = assets?[indexPath.item] {

            let option = PHImageRequestOptions()
            option.isSynchronous = false
            option.resizeMode = .exact
            option.isNetworkAccessAllowed = true

            DispatchQueue.global(qos: .userInitiated).async {
                manager.requestImage(for: asset, targetSize: Constant.targetSize, contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in

                    DispatchQueue.main.async {

                        if cell.tag == indexPath.item {
                            cell.imageView.image = result
                        }
                    }
                })
            }
        }

希望,它可以帮助你