我有一个CollectionView,它在加载后显示缩略图。开始时,图片不会存储在设备上,因此它们会从服务器中获取。在从服务器获取这些图像后的回调方法中,它们的单元格不会更新,我需要将它们滚出屏幕,然后更新。我在另一个应用程序中有一个类似的机制,一切正常,我无法找到差异。以下是代码的一些部分,以便更好地理解我的工作。
这是我在检查缩略图是否已从服务器中取出后设置图像的代码。如果是这样,直接设置,如果没有,使用Alamofire检索图片并在完成加载后更新它。
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.reuseIdentifier, for: indexPath) as! PictureCollectionViewCell
/* Set thumbnail to the cell */
if let thumbnail = pictures[indexPath.row].thumbnail {
cell.imageView.image = thumbnail
} else {
pictures[indexPath.row].retrievePicture(thumbnail: true, completion: { picture in
cell.imageView.image = picture
})
}
return cell
}
如前所述,在我将单元格滚出可见屏幕区域之前,它不会更新。 cell或collectionView重新加载并没有解决问题。有什么想法吗?
提前致谢。
答案 0 :(得分:4)
因为块在后台线程中执行。你必须在主线程中更新UI。使用下面的代码
pictures[indexPath.row].retrievePicture(thumbnail: true, completion: { picture in
DispatchQueue.main.async {
cell.imageView.image = picture
}
})
答案 1 :(得分:1)
您可能会发现在indexPath上重新加载项目而不是使用以下方法重新加载整个表格会更好:
collectionView.reloadItemsAtIndexPaths(yourIndexPath)
答案 2 :(得分:1)
可能在后台线程中进行提取,因此也可以从中调用回调函数。无法从后台线程更新UI。 所以在你的提取回调中尝试使用这样的东西:
DispatchQueue.main.async {
collectionView.reloadData()
}
或者
DispatchQueue.main.async {
collectionView.reloadItems(indexPaths)
}
答案 3 :(得分:0)