我正在实现一个具有 Pinterest 风格的 2 列布局的应用程序。并希望每个单元格的大小动态对应于图像的大小。
我使用 SDWebImage 将图像异步加载到单元格,然后使 collectionView 的布局无效。然而,由于单元格是可重用的,因此每次屏幕上下滚动时,布局都会失效并产生一些不需要的动画。
这是我的代码:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell = collectionView.dequeueReusableCellWithReuseIdentifier(self.identifier, forIndexPath: indexPath) as! MyCell
cell.imageView.sd_setImageWithURL(imageUrl, completed: { (image, error, _, _) -> Void in
UIView.animateWithDuration(0.3, animations: { () -> Void in
collectionView.collectionViewLayout.invalidateLayout()
})
})
return cell
}
像元大小函数:
func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize {
var width = UIScreen.mainScreen().bounds.size.width / 2 - 3
// create a cell size from the image size, and return the size
if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? CraveCollectionViewCell{
if cell.imageView.image != nil {
let image = cell.imageView.image!
var height = image.size.height * width / image.size.width
let size = CGSize(width: width, height: height)
var height1 = size.height > 160 ? size.height : 160
return CGSize(width: width, height: height1)
}
}
return CGSize(width: width, height: 160)
}
}
当 SDWebImage 首先加载图像时,将调用 collectionView.collectionViewLayout.invalidateLayout()
并且布局工作正常。
滚动后,collectionView.collectionViewLayout.invalidateLayout()
再次被调用,这就是问题所在。
最佳答案
最初,我的单元格大小是在 SDWebImage 获取图像后通过图像计算的,这是异步的,也是导致抖动的原因。
所以为了解决这个问题,服务器应该首先返回图像的大小,这样单元格大小就不会被异步计算。
关于ios - UICollectionView 异步更新大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32434348/