2017-04-24 79 views
1

我有一个CollectionView显示加载后的缩略图。开始时,图片不会存储在设备上,以便从服务器获取图片。在从服务器获取这些图像后的回调方法中,它们的单元格不会更新,我需要将它们滚动到屏幕外,然后才能更新。我在另一个应用程序中有类似的机制,那里一切正常,我找不到差异。下面是代码的一些部分,以便更好地理解我所做的事情。UICollectionViewCell不更新图像,如果可见

这是我在检查缩略图是否已从服务器获取后设置图像的代码。如果是这样,直接设置,如果不是,使用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 
} 

如前所述,它不更新,直到我滚动单元格出可视屏幕区域。单元格或collectionView重新加载没有解决问题。有任何想法吗?

在此先感谢。

+0

是否调用了封闭'retrievePicture()'?什么代码呢? – Larme

+1

到图像下载时,单元显示完成。您需要在集合视图上调用'reloadData()'来刷新UI。 – lukya

+0

完成下载运行的线程是什么? – Fogmeister

回答

0

好球员,这是你能想象的最愚蠢的错误。从异步回调方法更新UI可以正常工作。我忘了从异步任务中调用回调方法。问题解决了,谢谢你的帮助。

4

因为该块在后台线程中执行。你必须在主线程中更新UI。使用下面

pictures[indexPath.row].retrievePicture(thumbnail: true, completion: { picture in 
      DispatchQueue.main.async { 
        cell.imageView.image = picture 
       } 
     }) 
+0

它不会改变行为 –

1

这段代码你可能会发现它更好地只需重新加载,而不是重新加载使用整个表在indexPath项目:

collectionView.reloadItemsAtIndexPaths(yourIndexPath) 
+0

我试过这个之前,什么也没发生 –

1

抓取是在后台线程可能发生的事情让你的回调函数也被调用。 UI不能从后台线程更新。 所以在你取的回调尝试使用这样的:

DispatchQueue.main.async { 
    collectionView.reloadData() 
} 

或者

DispatchQueue.main.async { 
    collectionView.reloadItems(indexPaths) 
} 
+0

和以前一样的行为,没有改变任何东西 –