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

Kev*_*lia 17 objective-c ios uicollectionview ios7

所以我试图编写一些代码来将集合视图滚动到某个索引,然后拉入对单元格的引用并执行一些逻辑.但是我注意到如果在滚动之前该单元格当前不可见,则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]];
Run Code Online (Sandbox Code Playgroud)

是否有一些其他的方法我必须调用,cellForItemAtIndexPath以便为一个单元格返回一些东西突然出现在它前面的滚动的结果?

Kev*_*lia 21

我现在想出了一个解决方案.如果我[myView layoutIfNeeded]在调用reloadData后立即调用,但在我尝试检索单元格之前一切正常.现在所有单元都被缓存,因此访问速度很快,但是如果我必须从Web或内部数据库加载,我可能会给我带来糟糕的性能,但我们会看到.


hfo*_*sli 17

如果要访问单元格并使其在屏幕上可见:

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];
}
Run Code Online (Sandbox Code Playgroud)

我很少进入第二个if语句,但有两个这样的后退非常有效.

  • 我搜索了很长时间强制collectionView显示某个单元格作为焦点和选择,你的方法(看起来很昂贵)是唯一的工作解决方案,感谢您投入时间来建议它, (5认同)

Tim*_*ose 12

根据你的评论,这听起来像你最终的细胞框架.在不依赖单元格存在的情况下执行此操作的方法是询问集合视图的布局:

NSIndexPath *indexPath = ...;
UICollectionViewLayoutAttributes *pose = [self.collectionView.collectionViewLayout layoutAttributesForItemAtIndexPath:indexPath];
CGRect frame = pose.frame;
Run Code Online (Sandbox Code Playgroud)