简体   繁体   English

iOS(Swift):对于不可见的单元格,集合视图indexPath(for:cell)为nil

[英]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 : 我有一个UIViewControllerUICollectionView使用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: 该单元的唯一任务是:

  1. to display data and 显示数据和
  2. receive user input 接收用户输入

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.

相关问题 UITableView的indexPath(用于单元格:UITableViewCell)-> IndexPath? 返回零的可见细胞 - UITableView's indexPath(for cell: UITableViewCell) -> IndexPath? returning nil for visible cells 如何获取集合视图单元格的indexPath - How to get the indexPath of a collection view cell Swift iOS:从自定义单元类获取单元的IndexPath - Swift iOS: Getting Cell's IndexPath From Custom Cell Class 无法在集合视图中循环所有可见和不可见单元格并更改单元格属性 - Not able to loop all visible and non visible cell in collection view and change the cell property CollectionView cellForItemAt indexPath可以使单元出队,但单元的视图为nil - CollectionView cellForItemAt indexPath does deque cells but cell's view is nil 表格视图单元格内的嵌套集合视图 swift iOS - Nested Collection View inside of table view cell swift iOS iOS Swift:自动调整大小的集合视图嵌套在表格视图单元格中 - iOS swift: autoresize collection view nested inside a table view cell 如何使用集合视图单元格Swift iOS实现网格视图 - How to achieve Grid view using collection view cell swift ios 如何将集合视图单元格的indexPath传递给另一个视图控制器 - How to pass a collection view cell's indexPath to another view controller UICollectionView:获取不可见的Cell的indexPath - UICollectionView: Get indexPath of Cell that is not visible
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM