55

我有一个水平UICollectionView的工作正常和滚动。当我点击一个项目时,我会更新我的数据并调用reloadData. 这有效,新数据显示在UICollectionView. 问题是滚动位置没有改变,它仍在查看最后一个位置。我想将滚动重置到顶部(或者在我的情况下是左侧)。我怎样才能做到这一点?

4

9 回答 9

174

你想要setContentOffset:。它需要一个 CGPoint 作为参数,您可以使用 CGPointMake 将其设置为您想要的任何内容,但是如果您希望返回到集合的最开始,您可以简单地使用 CGPointZero。

[collectionView setContentOffset:CGPointZero animated:YES];
于 2013-03-20T10:25:20.200 回答
34

您可以使用此方法滚动到您想要的任何项目:

- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath 
               atScrollPosition:(UICollectionViewScrollPosition)scrollPosition 
                       animated:(BOOL)animated
于 2013-03-20T10:25:52.533 回答
23

我经常在我的应用程序的不同部分使用它,所以我只是扩展了 UIScrollView 以便它可以用于任何滚动视图和滚动视图子类:

extension UIScrollView {        
    /// Sets content offset to the top.
    func resetScrollPositionToTop() {
        self.contentOffset = CGPoint(x: -contentInset.left, y: -contentInset.top)
    }
}

所以每当我需要重置位置时:

self.collectionView.resetScrollPositionToTop()
于 2015-10-30T11:38:06.603 回答
13

在斯威夫特:

collectionView.setContentOffset(CGPointZero, animated: true)

如果您离开包含集合视图的视图,请在第二个视图控制器中进行更改,并且需要在返回时更新集合视图:

@IBAction func unwindTo_CollectionViewVC(segue: UIStoryboardSegue) {
    //Automatic table reload upon unwind
    viewDidLoad()
    collectionView.reloadData()
    collectionView.setContentOffset(CGPointZero, animated: true)
}

在我的情况下,展开非常好,因为 viewDidLoad 调用将更新 CoreData 上下文,reloadData 调用将确保 collectionView 更新以反映新的 CoreData 上下文,然后 contentOffset 将确保表设置回顶部。

于 2015-09-01T07:56:24.687 回答
7

如果您查看控制器包含安全区域,代码:

collectionView.setContentOffset(CGPointZero, animated: true)

不起作用,因此您可以使用通用扩展:

extension UIScrollView {
    func scrollToTop(_ animated: Bool) {
        var topContentOffset: CGPoint
        if #available(iOS 11.0, *) {
            topContentOffset = CGPoint(x: -safeAreaInsets.left, y: -safeAreaInsets.top)
        } else {
            topContentOffset = CGPoint(x: -contentInset.left, y: -contentInset.top)
        }
        setContentOffset(topContentOffset, animated: animated)
    }
}
于 2018-11-28T05:38:17.520 回答
6

在我的例子中,CGPointZero 改变了集合视图的内容,因为你没有计算内容插图。这对我有用:

    CGPoint topOffest = CGPointMake(0,-self.collectionView.contentInset.top);
    [self.collectionView setContentOffset:topOffest animated:YES];
于 2016-07-14T08:05:26.127 回答
4

抱歉,在撰写本文时我无法发表评论,但我使用的是 UINavigationController 并且CGPointZero它本身并没有让我达到最高点,所以我不得不使用以下内容。

CGFloat compensateHeight = -(self.navigationController.navigationBar.bounds.size.height+[UIApplication sharedApplication].statusBarFrame.size.height);
[self.collectionView setContentOffset:CGPointMake(0, compensateHeight) animated:YES];

希望这对将来的人有所帮助。干杯!

于 2014-07-14T12:05:55.777 回答
2

为了处理UINavigationController一个透明的导航栏,我必须计算额外的顶部偏移量以完美匹配第一个元素的位置。

斯威夫特 1.1 代码:

     let topOffest = CGPointMake(0, -(self.collectionView?.contentInset.top ?? O))
     self.collectionView?.setContentOffset(topOffest, animated: true)

干杯!

于 2015-05-15T08:15:30.627 回答
0
  • SWIFT 4.2 解决方案-假设我有一个 tableView,每个 tableViewCell 包含一个 Horizo​​ntalCollectionView 由于单元格的重用,即使第一个 tableViewCell 向下滚动到第 4 页,其他单元格也设置为第 4 页。

这适用于这种情况 - 在 tableView 中的 cellForRowAt 函数中,让 cell = //使用 deque cell.myCollectionView.contentOffset = CGPoint(x:0,y:0) 声明一个单元格

于 2019-07-25T09:55:21.733 回答