我正在Swift中编写一个简单的自定义照片选择器。看看GIF,你会发现它有什么问题:
当我点击状态栏到quickly
滚动到顶部时,图片全部混淆,因为正在重复使用单元格并且重新生成缩略图需要很短的时间,因此,会发生这种情况。我想知道无论我滚动多快,我怎么能解决这个问题?我的这个选择器的代码是:
func getThumbnail(asset: PHAsset, targetSize: CGSize, onComplete: @escaping (UIImage?, [AnyHashable: Any]?) -> ()) {
let manager = PHImageManager.default()
let option = PHImageRequestOptions()
option.resizeMode = .fast
option.isNetworkAccessAllowed = true
manager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: option) { (thumbnail, info) in
onComplete(thumbnail, info)
}
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = ...
let asset = photos[indexPath.row] // "photos" is an array of all photos in library
// and its type is "[PHAsset]"
let photoSize = collectionView.frame.width / 3
getThumbnail(asset: asset, targetSize: CGSize(width: photoSize, height: photoSize, onComplete: { (image, _) -> Void in
(cell.viewWithTag(1) as! UIImageView).image = image
// A cell has a UIImageView, whose size is equal to cell size,
// whose tag = 1
}))
return cell
}
答案 0 :(得分:0)
在你的cellForItemAt第一行放
cell.imageView.image = nil
这样可以防止出列的单元重复使用可以减少闪烁的图像。如果图像在内存中,它会立即被替换,没有问题。
仅仅因为您使用缓存并不意味着您的所有图像当前都在内存中。当您将图像读取到内存时会发生闪烁,尤其是在网络上以及需要调整单元格大小时(尽管看起来大小相同)。
您可能只想考虑在滚动结束时更新视图ONCE,而不是每个单元格。
您可以检查scrollViewWillBeginDragging以关闭更新,并在需要时检查scrollViewDidEndDecelerating以进行更新。
答案 1 :(得分:0)
我在UITableView
中遇到了同样的问题。当我使用AlamofireImage时
af_setImage(withURL: URL(string: pictureUrl))
然后我使用AlamofireImage&#39>
af_setImage(withURL: URL(string: pictureUrl)!, placeholderImage: UIImage(named: "YourPlaceholder.png"))
使用占位符图片解决问题。
答案 2 :(得分:0)
从你的代码:
let cell = ...
此时,您还没有图像,因此您应该将图像视图的图像设置为nil
或占位符图像:
let cell = ...
(cell.viewWithTag(1) as! UIImageView).image = placeholderImage
同样来自您的代码:
getThumbnail(asset: asset, targetSize: CGSize(width: photoSize, height: photoSize, onComplete: { (image, _) -> Void in
(cell.viewWithTag(1) as! UIImageView).image = image
此时,cell
可能不再是原始索引路径(因此对于image
)的正确单元格。原始索引路径可能没有单元格,或者索引路径可能有不同的单元格。您需要向集合视图询问正确的单元格:
getThumbnail(asset: asset, targetSize: CGSize(width: photoSize, height: photoSize, onComplete: { (image, _) -> Void in
guard let cell = collectionView.cellForItem(at: indexPath) else { return }
(cell.viewWithTag(1) as! UIImageView).image = image