[英]iOS (Swift): Collection View indexPath(for: cell) is nil for non visible cell
I have a UIViewController
that populates a UICollectionView
with an array of type Object
: 我有一个
UIViewController
, UICollectionView
使用Object
类型的数组填充UICollectionView
:
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") }
}
}
The collectionView
cells are represented by: 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 ...
}
}
which has a delegate
that talks to MyViewController
to get the Object
instance that is representing: 它有一个与
MyViewController
对话以获取表示以下内容的Object
实例的delegate
:
protocol MyCellDelegate: class {
func object(for cell: MyCell) -> Object
}
This works fine when I scroll down between cells however, it crashes at guard let indexPath = self.collectionView.indexPath(for: cell) ...
for cells that are off the screen when the apply(_ layoutAttributes: UICollectionViewLayoutAttributes)
method is called. 当我在单元格之间向下滚动时,此方法可以正常工作,但是,当调用
apply(_ layoutAttributes: UICollectionViewLayoutAttributes)
方法时,对于不在屏幕上的guard let indexPath = self.collectionView.indexPath(for: cell) ...
,它会在guard let indexPath = self.collectionView.indexPath(for: cell) ...
崩溃guard let indexPath = self.collectionView.indexPath(for: cell) ...
。
Is there a way to fix this? 有没有办法解决这个问题? The cells need to know which instance of
Object
they are representing so that the view controller can tweak the model. 单元需要知道它们代表的是哪个
Object
实例,以便视图控制器可以调整模型。
Thanks a lot for any help! 非常感谢您的帮助!
Always assume that if a cell is offscreen, then the collection view has already recycled it. 始终假定如果某个单元格不在屏幕上,则说明该集合视图已经对其进行了回收。 The collection view constantly does this to keep memory usage low and performance high.
收集视图会不断这样做,以保持较低的内存使用量和较高的性能。
To perform some action offscreen, what I often do is hold a separate object (view model, in MVVM) that a visible cell can attach to. 为了在屏幕外执行一些操作,我通常要做的是持有一个可视单元格可以附加到的单独对象(MVVM中的视图模型)。 This object is owned and retained by my objects and is never recycled.
该对象归我的对象所有和保留,并且永不回收。 If I need to do any offscreen action, this object does it.
如果我需要执行任何屏幕外操作,则此对象会执行此操作。
The cell's only jobs are: 该单元的唯一任务是:
Both of those require it to be visible. 这两个都要求它是可见的。
When I create cells, I use prepareForReuse
to detach it from the previous view model and do necessary clean up before attaching the cell to the next one. 创建单元格时,可以使用
prepareForReuse
将其与上一个视图模型分离,并在将单元格附加到下一个视图模型之前进行必要的清理。
Alternate Solution 替代解决方案
If all you need is the index path to get your special object, you could simply use the index path from the layout attributes. 如果您只需要获取特殊对象的索引路径,则可以简单地使用布局属性中的索引路径。
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 ...
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.