PHCachingImageManager.requestImage 总是调用两次?

PHCachingImageManager.requestImage is always called twice?

我有一个带有自定义 UICollectionViewCellUICollectionView,应该从照片中获取并显示缩略图(低质量)照片(通常用户可以 select 多于 1 张照片)在单元格中的每个 UIImageView 中。

我一直在研究 PHImageRequestOptions 及其属性,阅读有关它们的信息。在某种程度上,我什至将 nil 作为 requestImage(for: PHAsset) 方法的参数传递,因为我不确定我哪里错了。

问题是 requestImage(for: PHAsset) 方法被调用了两次。我需要第一次调用它只是为了在每个集合视图单元格中设置低质量的图像(缩略图),一旦全尺寸图像准备就绪,它应该添加到名为 assetsTurnedIntoImages 的图像数组中.问题是我做错了什么,我总是会调用 ifelse 方法两次,所以基本上,如果我从相机胶卷中 select 编辑了 4 张图像(因此,我在 assets 数组中有 4 张图片)当它们通过 requestImage(for: asset) 方法时,我在 assetsTurnedIntoImages 中得到 8 张图片而不是 4 张。所以这是我的代码

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        print("Assets count is:", assets.count)
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoPostCVCell", for: indexPath) as! PhotoPostCVCell
        if let takenImage = cameraPhotoUIImage
        {
            cell.cellImage.image = takenImage
        }
        if assets.count > 0
        {
            let asset = assets[indexPath.row]

//            var imageRequestOptions: PHImageRequestOptions
//            {
//                let options = PHImageRequestOptions()
//                //options.version = .current
//                //options.resizeMode = .exact
//                //options.deliveryMode = .fastFormat
//                options.isSynchronous = true
//                return options
//            }
            let targetSize = CGSize(width: asset.pixelWidth, height: asset.pixelHeight)
            imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: nil)
            { (image, info) in
                if image != nil
                {
                    let imageQualityState = info![PHImageResultIsDegradedKey] as! Bool

                    if imageQualityState
                    {
                        print("LOW QUALITY")
                        print("Image Quality State is:", imageQualityState)
                        cell.cellImage.image = image
                        print(image!.size)
                    }
                    else
                    {
                        print(image!.size)
                        cell.cellImage.image = image
                        self.assetsTurnedIntoImages.append(image!)
                    }
                }
            }
        }
        return cell
    }

恐怕您对 requestImage:forAsset 被调用两次无能为力。但是,您可以更改将图像放入数组的方式以避免重复。我可以建议:

self.assetsTurnedIntoImages[indexPath.row] = image

这将导致第二次传递完成的图像替换第一次调用的图像,避免重复。

您需要提前为您的数组预初始化足够 space,这样 indexPath.row 就不会尝试越界访问您的数组。 在 ViewDidLoad 中添加一些内容以达到以下效果:

self.assetsTurnedIntoImages = [UIImage](repeating: UIImage(), count: assets.count)

您可以通过包含以下条件来丢弃那些低分辨率重复项:

imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: nil) { (image, info) in

let isDegraded = (info?[PHImageResultIsDegradedKey] as? Bool) ?? false
if isDegraded {
   return
}