首先,我创建一个带有故事板的集合视图控制器,并将一个单元(称为RouteCardCell
)子类化。
延迟的单元格从Web加载图像。为此,我创建了一个加载图像的线程。加载图像后,我调用方法reloadItemsAtIndexPaths:
来显示图像。
正确加载图片,但显示图片时出现问题。只有在屏幕上滚动并重新打开后,我的单元格才会显示新图像。
重新加载项目后,为什么我的图像无法正常显示?
以下是相关代码:
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as RouteCardCell
let road = currentRoads[indexPath.item]
cell.setText(road.title)
var imageData = self.imageCache.objectForKey(NSString(format: "%d", indexPath.item)) as? NSData
if let imageData_ = imageData{
cell.setImage(UIImage(data: imageData_))
}
else{
cell.setImage(nil)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
var Data = self.getImageFromModel(road, index:indexPath.item)
if let Data_ = Data{
self.imageCache.setObject(Data_, forKey: NSString(format: "%d", indexPath.item))
NSLog("Download Image for %d", indexPath.item)
}
else{
println("nil Image")
}
})
self.reloadCollectionViewDataAtIndexPath(indexPath)
}
return cell
}
func reloadCollectionViewDataAtIndexPath(indexPath:NSIndexPath){
var indexArray = NSArray(object: indexPath)
self.collectionView!.reloadItemsAtIndexPaths(indexArray)
}
func getImageFromModel(road:Road, index:Int)->NSData?{
var images = self.PickTheData!.pickRoadImage(road.roadId)
var image: Road_Image? = images.firstObject as? Road_Image
if let img = image{
return img.image
}
else{
return nil
}
}
答案 0 :(得分:1)
在下载图片之前,您正在调用reloadCollectionViewDataAtIndexPath(indexPath)
。不要在dispatch_async
块之外调用它,而是在完成后添加另一个块以返回主队列。
例如:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
// download the image…
// got the image, now update the UI
dispatch_async(dispatch_get_main_queue()) {
self.reloadCollectionViewDataAtIndexPath(indexPath)
}
})
这在iOS开发中是一个非常棘手的问题。还有其他情况你无法处理,比如如果用户滚动得非常快,你最终会得到一堆用户甚至不需要看到的下载。您可能希望尝试使用类似SDWebImage的库,这对您当前的实现有很多改进。