swift - 滚动时collectionView单元格图像更改 - 快速 - 以编程方式
问题描述
我需要UIcollectionViewcell
使用URL
我在初始化期间传递的一个 ImageView 加载内部:
func configureCellWith(messageModel : MessageModel){
guard let url = URL(string: messageModel.contentUrl!) else { return }
if url.isURLPhoto(){
likedImageView.sd_setImage(with: url, placeholderImage: nil)
}
else if url.isURLVideo(){
getThumbnailImageFromVideoUrl(url: url) { (image) in
self.likedImageView.image = image
}
}
如果 url 是视频,我需要使用这种方法以这种方式加载图像:
func getThumbnailImageFromVideoUrl(url: URL, completion: @escaping ((_ image: UIImage?)->Void)) {
DispatchQueue.global().async {
let asset = AVAsset(url: url)
let avAssetImageGenerator = AVAssetImageGenerator(asset: asset)
avAssetImageGenerator.appliesPreferredTrackTransform = true
let thumnailTime = CMTimeMake(value: 2, timescale: 1)
do {
let cgThumbImage = try avAssetImageGenerator.copyCGImage(at: thumnailTime, actualTime: nil)
let thumbNailImage = UIImage(cgImage: cgThumbImage)
DispatchQueue.main.async {
completion(thumbNailImage)
}
} catch {
print(error.localizedDescription)
DispatchQueue.main.async {
completion(nil)
}
}
}
}
可见我检索视频的初始帧并将其加载到单元格中,显然因为它是一个异步函数,加载图像需要一些时间,这没有问题。
当我滚动浏览集合时会出现问题,我看到某些单元格显示的图像与正确的图像不对应。
在线搜索我发现我需要清除prepareForReuse
单元格中的图像,所以我这样做了(如果图像是通过函数加载的sd_setImage
)getThumbnailImageFromVideoUrl
:
override func prepareForReuse() {
super.prepareForReuse()
self.likedImageView.image = UIImage()
self.likedImageView.image = nil
self.likedImageView.sd_cancelCurrentImageLoad()
}
但是当滚动时我仍然得到图像不匹配的想法collection view
,可能是什么问题?
解决方案
我认为问题不在于图像,我猜它与视频缩略图有关。您在后台线程上同步生成缩略图,但是在将其设置回 imageView 时,您从不费心查找单元格是否被重用以及您刚刚创建的图像是否已过时。
所以在你的牢房里
var currentModel: MessageModel! = nil //declare a instance variable to hold model
... other code
func configureCellWith(messageModel : MessageModel){
self.currentModel = messageModel //keep a copy of model passed to u as argument
guard let url = URL(string: messageModel.contentUrl!) else { return }
if url.isURLPhoto(){
likedImageView.sd_setImage(with: url, placeholderImage: nil)
}
else if url.isURLVideo(){
getThumbnailImageFromVideoUrl(url: url) { (image) in
self.likedImageView.image = image
}
}
终于在getThumbnailImageFromVideoUrl
func getThumbnailImageFromVideoUrl(url: URL, completion: @escaping ((_ image: UIImage?)->Void)) {
DispatchQueue.global().async {
let asset = AVAsset(url: url)
let avAssetImageGenerator = AVAssetImageGenerator(asset: asset)
avAssetImageGenerator.appliesPreferredTrackTransform = true
let thumnailTime = CMTimeMake(value: 2, timescale: 1)
do {
let cgThumbImage = try avAssetImageGenerator.copyCGImage(at: thumnailTime, actualTime: nil)
let thumbNailImage = UIImage(cgImage: cgThumbImage)
if url.absoluteString == currentModel.contentUrl { //check if image you generated is still valid or its no longer needed
DispatchQueue.main.async {
completion(thumbNailImage)
}
}
} catch {
print(error.localizedDescription)
DispatchQueue.main.async {
completion(nil)
}
}
}
推荐阅读
- javascript - 使用nodejs fs.writeFile在文件中写入相同的格式
- arrays - 如何在 Julia 中获取数组的大小?
- c# - Firebase数据库数据提取排序问题
- javascript - 如何让源地图在 Webpack 中工作?
- javascript - 捕获异步函数中的错误并通过 jest 进行测试
- c++ - 我需要根据 timeval 删除向量元素
- android - 在 Ionic 4 中处理后退按钮的问题
- svg - 如何使用 Javascript 在圆形 SVG 内添加文本?
- python - 为什么我的箱线图没有出现在 python 中?
- git - .gitignore 不会忽略包含 .git 子目录的目录吗?