我有一个带图像的集合视图,我使用Alamofire和AlamofireImage作为网络代码。 在cellForItemAtIndexPath的开头,我将图像设置为nil并使用request?.cancel()取消任何正在进行的请求(如果存在)。 但这样做,一些单元格根本不会填充图像。 你能告诉我我做错了什么吗? 请参阅下面的cellForItemAtIndexPath代码:
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! StoreCell
let entry = self.dataCell.addCell[indexPath.section][indexPath.item]
stringURL = "https://website.com/stories_db/images/\(entry.filename)"
cell.title.text = entry.title
cell.subTitle.text = entry.author
cell.cost.text = entry.cost
// Reset the cell
cell.storyImage.image = nil
// request?.cancel()
if let image = dataCell.cachedImage(stringURL) {
cell.storyImage.image = image
} else {
request = dataCell.getNetworkImage(stringURL) { image in
cell.storyImage.image = image
}
}
// Fix the collection view cell in size
cell.contentView.frame = cell.bounds
cell.contentView.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
return cell
}
答案 0 :(得分:1)
您似乎正在重复使用一个名为var的请求来存储图像请求。如果一次可以看到多个集合视图单元格,则可能需要一次创建多个异步图像请求,因此您需要一种方法来存储多个正在进行的请求。
例如,如果您的集合视图有三个单元格并且所有单元格都可见,那么当它重新加载时,它将调用cellForItemAtIndexPath来获取第一个单元格。您的代码会创建单元格并启动"图像1"的异步请求。并将其存储在您的请求var。
中然后集合视图立即再次调用cellForItemAtIndexPath以获取第二个单元格。如果请求"图像1"仍然在进行中,调用请求?.cancel()会中断它所以"图像1"永远不会完成下载。然后代码为"图像2"创建新请求。并将其分配给请求。
集合视图立即调用cellForItemAtIndexPath来获取第三个单元格......
一种解决方案是存储活动请求的数组(或字典)。在您创建请求时添加请求,请求在请求完成时删除(失败或成功)。然后,如果您确定您正在重复使用的单元格正在进行请求,请取消该请求并将其从列表中删除。
另一种方法是创建一个自定义单元子类并让它存储活动请求。这样做的好处是可以更简单地将请求与单元格关联起来。
使用这两种方法,您可能需要考虑在UICollectionViewCell.prepareForReuse()而不是cellForItemAtIndexPath中取消对单元格的活动请求。