PHCachingImageManager.requestImage 总是被调用两次?
Posted
技术标签:
【中文标题】PHCachingImageManager.requestImage 总是被调用两次?【英文标题】:PHCachingImageManager.requestImage is always called twice? 【发布时间】:2017-09-20 14:23:04 【问题描述】:我有一个带有自定义UICollectionViewCell
的UICollectionView
,它应该从单元格中的每个UIImageView
中的照片(通常用户可以选择多于一张照片)中获取并显示缩略图(低质量)照片。
我一直在玩PHImageRequestOptions
及其属性,阅读它们。我什至将nil
作为requestImage(for: PHAsset)
方法的参数传递,因为我不确定我错在哪里。
问题是requestImage(for: PHAsset)
方法被调用了两次。我需要第一次调用它以在每个集合视图单元格中以低质量(缩略图图像)设置图像,一旦完整尺寸的图像准备好,它应该被添加到一个名为assetsTurnedIntoImages
的图像数组中。问题是我做错了,我总是得到if
和else
方法调用两次,所以基本上,如果我从相机胶卷中选择了 4 张图像(因此,我在assets 数组),当他们通过 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
【问题讨论】:
【参考方案1】:您可以通过包含以下条件来丢弃那些低分辨率副本:
imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: nil) (image, info) in
let isDegraded = (info?[PHImageResultIsDegradedKey] as? Bool) ?? false
if isDegraded
return
【讨论】:
【参考方案2】:担心requestImage:forAsset
被调用两次,您无能为力。但是,您可以更改将图像放入数组的方式以避免重复。我可以建议:
self.assetsTurnedIntoImages[indexPath.row] = image
这将导致第二次传入完成的图像替换第一次调用的图像,避免重复。
您需要提前为您的数组预初始化足够的空间,以便indexPath.row
不会尝试越界访问您的数组。
在ViewDidLoad
中添加以下内容:
self.assetsTurnedIntoImages = [UIImage](repeating: UIImage(), count: assets.count)
【讨论】:
我遇到了崩溃。我收到一个错误fatal error: Array index is out of range
嗯,他们不能按顺序被调用,假设 requestImage
在图像 3 被调用之前在图像 1 被调用。我会更新我的答案。
我按照你的建议做了,但是assetsTurnedIntoImages
现在的图片数量是原来的三倍。如果我从照片中选择了 4 个评估,我会在数组中得到 12 个图像。
您有 12 个资产吗? ViewDidLoad
中的 assets.count
是什么?
不,是 4。这就是它如此令人困惑的原因。我不明白为什么它们现在增加了两倍。以上是关于PHCachingImageManager.requestImage 总是被调用两次?的主要内容,如果未能解决你的问题,请参考以下文章