嵌套横向UICollectionView复用混乱:滚动时单元格内容错乱
解决嵌套UICollectionView复用后内容错乱的问题
我之前碰到过完全一样的嵌套CollectionView复用坑,你的核心问题在于父单元格复用时,内部的横向CollectionView没有及时清空旧数据并刷新,再加上SDWebImage的异步加载特性,导致内容/图片互相串位。下面是分步的解决方案:
1. 修复CarsCell的复用逻辑
父单元格CarsCell被复用时,必须重置数据源并强制刷新内部的横向CollectionView,否则它会保留上一次的内容。修改prepareForReuse和car属性的didSet:
class CarsCell: BaseCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { // ... 其他代码不变 var car: CarModel.Car? { didSet { carNameView.text = car?.title // 关键:数据更新后立即刷新横向CollectionView cellCollectionView.reloadData() } } override func prepareForReuse() { super.prepareForReuse() // 重置数据源,彻底清空旧数据残留 self.car = nil // 强制刷新内部CollectionView,确保显示空白状态 self.cellCollectionView.reloadData() } // ... 其他代码不变 }
2. 解决CarItemCell的图片加载错乱问题
SDWebImage的异步加载会导致:当单元格被复用后,之前的图片请求还在后台运行,完成后会覆盖新设置的图片。所以在prepareForReuse里要主动取消当前的加载请求,并重置为占位图:
class CarItemCell: BaseCell { // ... 其他代码不变 override func prepareForReuse() { super.prepareForReuse() // 取消当前的图片加载请求,防止旧图片"串"到新单元格 thumbnailView.sd_cancelCurrentImageLoad() // 重置为占位图,而不是空图,提升用户体验 self.thumbnailView.image = UIImage(named: "processing") self.carLabel.text = "" self.owner.text = "" } // ... 其他代码不变 }
3. 优化横向CollectionView的布局稳定性
当父单元格CarsCell的尺寸变化时(比如屏幕旋转),横向CollectionView的cell尺寸计算可能出错,导致显示异常。可以在CarsCell里添加布局刷新逻辑:
class CarsCell: BaseCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { // ... 其他代码不变 override func layoutSubviews() { super.layoutSubviews() // 当父单元格布局变化时,刷新横向CollectionView的布局 if let flowLayout = cellCollectionView.collectionViewLayout as? UICollectionViewFlowLayout { flowLayout.invalidateLayout() } } // ... 其他代码不变 }
为什么之前的prepareForReuse没用?
你之前只重置了CarItemCell的内容,但父单元格复用后,内部的横向CollectionView并没有重新加载新数据——它还是拿着旧的car数据源在显示,直到新的car设置后才更新,但这个时机可能晚于单元格复用完成,导致短暂显示旧内容,再加上SDWebImage的异步加载延迟,就出现了内容错乱的情况。
内容的提问来源于stack exchange,提问作者learningswift
相关产品推荐
相关产品推荐

