强制滚动后,cellForItemAtIndexPath返回nil使其可见

所以我试图写一些代码滚动集合视图到一个特定的索引,然后拉引用到单元格,并做一些逻辑。 不过,我注意到,如果该单元格在滚动之前目前不可见,则cellForItemAtIndexPath调用将返回nil,导致我的逻辑的其余部分失败。

 [_myView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0] atScrollPosition:UICollectionViewScrollPositionTop animated:NO]; //Tried with and without this line, thinking maybe this would trigger a redraw [_myView reloadData]; //returns nil if cell was off-screen before scroll UICollectionViewCell *cell = [_myView cellForItemAtIndexPath: [NSIndexPath indexPathForItem:index inSection:0]]; 

有没有其他的方法,我必须调用导致cellForItemAtIndexPath返回一个单元格突然进入视图作为滚动的结果之前立即它的东西?

根据你的意见,这听起来像你最终在细胞的框架。 不依赖单元格存在的方法是询问集合视图的布局:

 NSIndexPath *indexPath = ...; UICollectionViewLayoutAttributes *pose = [self.collectionView.collectionViewLayout layoutAttributesForItemAtIndexPath:indexPath]; CGRect frame = pose.frame; 

现在我想出了一个解决scheme。 如果我调用reloadData之后调用[myView layoutIfNeeded] ,但是在我尝试检索单元格之前,一切正常。 现在所有的单元格都被caching了,所以访问速度很快,但是如果我不得不从networking或者内部数据库加载,这个可能会给我带来不好的performance,但是我们会看到。

如果你想访问单元格,并在屏幕上显示它:

 NSIndexPath *indexPath = ...; [collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically | UICollectionViewScrollPositionCenteredHorizontally animated:NO]; UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; if(cell == nil) { [collectionView layoutIfNeeded]; cell = [collectionView cellForItemAtIndexPath:indexPath]; } if(cell == nil) { [collectionView reloadData]; [collectionView layoutIfNeeded]; cell = [collectionView cellForItemAtIndexPath:indexPath]; } 

我很lessinput第二个if语句,但是像这样的两个倒退工作得很好。

hfossli的解决scheme为我工作,所以我提供了一个Swift版本下面。 在我的情况下,我无法获得对自定义UICollectionViewCell的引用,可能是因为它不可见。 我尝试了很多东西,但正如Shaybc所说,这是唯一的解决scheme。

Swift 3:

  func getCell(_ indexPath: IndexPath) -> CustCell? { cView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.centeredHorizontally, animated: false) var cell = cView.cellForItem(at: indexPath) as? CustCell if cell == nil { cView.layoutIfNeeded() cell = cView.cellForItem(at: indexPath) as? CustCell } if cell == nil { cView.reloadData() cView.layoutIfNeeded() cell = cView.cellForItem(at: indexPath) as? CustCell } return cell } 

用法:

 let indexPath = IndexPath(item: index, section: 0) cView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition(), animated: true) if let cell = getCell(indexPath) { cell. <<do what you need here>> }