我有一个UIViewController
,其中UICollectionView
填充了Object
类型的数组:
class MyViewController: UIViewController {
let objects: [Object]!
weak var collectionView: UICollectionView!
func object(for cell: MyCell) {
guard let indexPath = self.collectionView.indexPath(for: cell) else { fatalError("No cell at index path") }
}
}
collectionView
单元格由:
class MyCell: UICollectionViewCell {
weak var delegate: MyCellDelegate?
override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
super.apply(layoutAttributes)
let obj = self.delegate?.object(for: self)
// configure various subviews with obj ...
}
}
其delegate
与MyViewController
对话,以获取代表的Object
实例:
protocol MyCellDelegate: class {
func object(for cell: MyCell) -> Object
}
当我在单元格之间向下滚动时,这样可以正常工作,但是当调用guard let indexPath = self.collectionView.indexPath(for: cell) ...
方法时,对于屏幕外的单元格,它会在apply(_ layoutAttributes: UICollectionViewLayoutAttributes)
处崩溃。
有没有办法解决这个问题?单元格需要知道它们所代表的Object
个实例,以便视图控制器可以调整模型。
非常感谢您的帮助!
答案 0 :(得分:4)
始终假设如果单元格在屏幕外,则集合视图已经回收了它。集合视图不断地执行此操作以保持较低的内存使用率和高性能。
要在屏幕外执行某些操作,我经常做的是在可见单元格可以附加的单独对象(MVVM中的视图模型)中。此对象由我的对象拥有和保留,永远不会被回收。如果我需要执行任何屏幕外操作,则此对象会执行此操作。
该单元的唯一工作是:
这两个都要求它可见。
当我创建单元格时,我使用prepareForReuse
将其与上一个视图模型分离,并在将单元格附加到下一个单元格之前进行必要的清理。
替代解决方案
如果只需要获取特殊对象的索引路径,则只需使用布局属性中的索引路径即可。
protocol MyCellDelegate: class {
func object(for indexPath: IndexPath) -> Object
}
class MyCell: UICollectionViewCell {
weak var delegate: MyCellDelegate?
override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
super.apply(layoutAttributes)
let obj = self.delegate?.object(for: layoutAttributes.indexPath)
// configure various subviews with obj ...
}
}