Swift: 集合视图的惰性填充
Swift: lazy population of a collection view
我正在学习 Swift,并正在编写一个显示带有图像的集合视图的小应用程序。它不工作,图像永远不会显示。我在 collectionView cellForItemAtIndexPath
中看到奇怪的行为:当我延迟加载要在单元格中显示的图像并第二次调用 collectionView.dequeueReusableCellWithReuseIdentifier()
时,它 returns 是一个不同的单元格。这发生在我滚动集合视图之前,因此单元格重用应该不是问题。这是我的代码:
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let reuseIdentifier = "CollectionCell"
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath:indexPath) as! ImageCollectionCell
cell.imageView.contentMode = UIViewContentMode.ScaleAspectFill
cell.countLabel.text = "\(indexPath.row+1)"
let imageIndex = XKCDClient.sharedInstance.totalCount - indexPath.row - 1
println("loading image # \(imageIndex)")
XKCDClient.sharedInstance.loadComic(imageIndex, completion: { (comicData) -> Void in
if let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath:indexPath) as? ImageCollectionCell {
println("got image # \(imageIndex)")
cell.imageView.backgroundColor = UIColor.blackColor()
if(comicData.image != nil) {
// cell.imageView.image = comicData.image // (1)
cell.imageView.image = UIImage(named: "placeholder") // (2)
cell.setNeedsDisplay()
}
}
else {
println("cell \(imageIndex) already reused");
}
})
return cell
}
会发生什么:
- 为每个索引路径调用回调块
UIImage
对象被正确传递到回调块中
- 回调中对单元格的更改似乎没有任何效果(包括设置背景颜色)
- 回调中
collectionView.dequeueReusableCellWithReuseIdentifier()
返回的单元格与方法开头返回的单元格不同。这似乎是问题的根源。
谁能解释一下这是怎么回事?
不要在回调闭包中再次调用 dequeuReusableCellWithReuseIdentifier
,而是调用 cellForItemAtIndexPath
。注意:在单元格中设置图片时,必须在主线程中进行:
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let reuseIdentifier = "CollectionCell"
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! ImageCollectionCell
cell.imageView.image = nil
cell.imageView.contentMode = UIViewContentMode.ScaleAspectFill
cell.countLabel.text = "\(indexPath.row+1)"
let imageIndex = XKCDClient.sharedInstance.totalCount - indexPath.row - 1
XKCDClient.sharedInstance.loadComic(imageIndex, completion: { (comicData) -> Void in
if let img = comicData.image {
// Note: Set image in the main thread
dispatch_async(dispatch_get_main_queue()) {
cell.imageView.image = img
}
} else {
println("No image in comicData")
dispatch_async(dispatch_get_main_queue()) {
cell.imageView.image = nil
}
}
})
return cell
}
我正在学习 Swift,并正在编写一个显示带有图像的集合视图的小应用程序。它不工作,图像永远不会显示。我在 collectionView cellForItemAtIndexPath
中看到奇怪的行为:当我延迟加载要在单元格中显示的图像并第二次调用 collectionView.dequeueReusableCellWithReuseIdentifier()
时,它 returns 是一个不同的单元格。这发生在我滚动集合视图之前,因此单元格重用应该不是问题。这是我的代码:
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let reuseIdentifier = "CollectionCell"
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath:indexPath) as! ImageCollectionCell
cell.imageView.contentMode = UIViewContentMode.ScaleAspectFill
cell.countLabel.text = "\(indexPath.row+1)"
let imageIndex = XKCDClient.sharedInstance.totalCount - indexPath.row - 1
println("loading image # \(imageIndex)")
XKCDClient.sharedInstance.loadComic(imageIndex, completion: { (comicData) -> Void in
if let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath:indexPath) as? ImageCollectionCell {
println("got image # \(imageIndex)")
cell.imageView.backgroundColor = UIColor.blackColor()
if(comicData.image != nil) {
// cell.imageView.image = comicData.image // (1)
cell.imageView.image = UIImage(named: "placeholder") // (2)
cell.setNeedsDisplay()
}
}
else {
println("cell \(imageIndex) already reused");
}
})
return cell
}
会发生什么:
- 为每个索引路径调用回调块
UIImage
对象被正确传递到回调块中- 回调中对单元格的更改似乎没有任何效果(包括设置背景颜色)
- 回调中
collectionView.dequeueReusableCellWithReuseIdentifier()
返回的单元格与方法开头返回的单元格不同。这似乎是问题的根源。
谁能解释一下这是怎么回事?
不要在回调闭包中再次调用 dequeuReusableCellWithReuseIdentifier
,而是调用 cellForItemAtIndexPath
。注意:在单元格中设置图片时,必须在主线程中进行:
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let reuseIdentifier = "CollectionCell"
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! ImageCollectionCell
cell.imageView.image = nil
cell.imageView.contentMode = UIViewContentMode.ScaleAspectFill
cell.countLabel.text = "\(indexPath.row+1)"
let imageIndex = XKCDClient.sharedInstance.totalCount - indexPath.row - 1
XKCDClient.sharedInstance.loadComic(imageIndex, completion: { (comicData) -> Void in
if let img = comicData.image {
// Note: Set image in the main thread
dispatch_async(dispatch_get_main_queue()) {
cell.imageView.image = img
}
} else {
println("No image in comicData")
dispatch_async(dispatch_get_main_queue()) {
cell.imageView.image = nil
}
}
})
return cell
}