UICollectionView scrollToItemAtIndexPath: 并获得新的单元格位置

Posted

技术标签:

【中文标题】UICollectionView scrollToItemAtIndexPath: 并获得新的单元格位置【英文标题】:UICollectionView scrollToItemAtIndexPath: and get fresh cell position 【发布时间】:2014-02-27 15:42:18 【问题描述】:

我想将集合视图滚动到某个没有动画的屏幕外单元格,并在滚动后获取该单元格的位置。问题是集合视图(视觉上)正确滚动,但单元格框架仍然在屏幕外。这是我的代码:

NSIndexPath *path = [fetchedResultsController indexPathForObject:objectInCollection];
[collectionView scrollToItemAtIndexPath:path atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];
[collectionView layoutSubviews]; // or 'layoutIfNeeded', doesn't matter
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:path];
cellFrame = [cell.superview convertRect:cell.frame toView:nil]; // still not refreshed

我可以建议集合视图不立即应用滚动,所以我想找到应用滚动的方法。

--- 更新 ---

集合视图在前一个视图控制器中(所以我从代码中滚动它,然后弹出可见视图控制器)。

即使在以前的视图控制器的viewDidAppear: 方法中,单元格框架仍保持在屏幕外。准确地说,[cell.superview convertRect:cell.frame toView:nil]; 返回没有集合视图的contentOffset 的框架。所以CGRectOffset([cell.superview convertRect:cell.frame toView:nil], 0, -collectionView.contentOffset.y) 在屏幕上返回正确的单元格框。

【问题讨论】:

我不知道我是否正确理解了您的问题,但即使在滚动之后,您也应该为单元格获得相同的帧。滚动不会改变子视图的框架;只有 contentOffset 应该改变。或者你想在 UICollectionView 的超级视图坐标中获取框架? 【参考方案1】:

从您的问题陈述中我可以理解,您希望将视图之外的某个单元格设置为可见状态。

UICollectionView 计算时单元格放置在同一位置

(void)prepareLayout (void)layoutAttributes.. 方法。

在调用 invalidateLayout 或 reloaddata 之前,集合单元格的帧是固定的。只是你必须解决collectionview的contentOffset。 只需获取单元格框架并设置 contentOffset 以便您的单元格框架在屏幕上可见。希望对您有所帮助。

【讨论】:

谢谢,帕万。真的,我们应该将contentOffset 添加到单元格框架以获得屏幕位置。这种情况不同于常见的做法[cell.superview convertRect:cell.frame toView:nil]; 欢迎您。我认为您的方法用于在具有某些框架的单元格上获取触摸点时,该框架将位于屏幕框架之外。此方法将提供框架,就好像单元格具有父视图的框架一样。【参考方案2】:

单元格框架应该是正确的,我认为您根本不需要使用 convertRect。

cellFrame = cell.frame;

但是,您可能必须在集合视图加载后执行此操作。先调用[collectionView reloadData]。

还有一个layoutAttributesForItemAtIndexPath: 方法具有该单元格的属性。您可以在 indexPath 上调用它并以这种方式获取属性。

【讨论】:

GregP,感谢您提供有关 layoutAttributesForItemAtIndexPath: 的提示。不幸的是,问题并没有解决 - 在调用 scrollToItemAtIndexPath 之前和之后它保持不变的 cell.frame,即使我们调用 reloadData 没问题。对不起,它没有帮助。不太确定还有哪些其他选择。【参考方案3】:

尝试将滚动位置更改为 UICollectionViewScrollPositionBottom,这对我有用 -

[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:NO];

【讨论】:

以上是关于UICollectionView scrollToItemAtIndexPath: 并获得新的单元格位置的主要内容,如果未能解决你的问题,请参考以下文章

Cypress web自动化30-操作窗口滚动条(scrollTo)

如何使用平滑效果的 window.scrollTo() [关闭]

为啥 scrollTo() 方法不适用于 iframe?

如何在 window.scrollTo() 之外滚动页面

如何使用 JQuery $.scrollTo() 函数滚动窗口

有啥方法可以平滑地为 window.scrollTo(0, 1) 设置动画?