【问题标题】:Reset scroll on UICollectionView在 UICollectionView 上重置滚动
【发布时间】:2013-03-20 10:20:45
【问题描述】:

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

【问题讨论】:

  • 遇到此问题时能否显示您的代码?我试图让我的滚动视图在我重新加载数据时不滚动大声笑我遇到了与你的问题相反的问题!

标签: iphone objective-c ipad ios6 uicollectionview


【解决方案1】:

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

[collectionView setContentOffset:CGPointZero animated:YES];

【讨论】:

  • 如果collectionview启用刷新视图,它将显示刷新视图
  • +1 setContentOffset 也帮助我为 UIScrollView 工作。
  • 如果您使用的是contentInsets,您可以使用以下点作为您的内容偏移量CGPointMake(-collectionView.contentInset.left, -collectionView.contentInset.top)
  • 对我来说,接受的答案 (scrollToItemAtIndexPath) 会将滚动重置到第一行,这会将标题项 (viewForSupplementaryElementOfKind) 置于视野之外。 setContentOffset 到 CGPointZero 将滚动放置在完整的顶部,包括任何标题单元格。
  • 它还有一个优点是不需要验证索引路径是否存在(例如:空集合视图)
【解决方案2】:

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

- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath 
               atScrollPosition:(UICollectionViewScrollPosition)scrollPosition 
                       animated:(BOOL)animated

【讨论】:

  • 也不允许偏移
  • 算了,下面的评论解决了。 [collectionView setContentOffset:CGPointZero 动画:YES];
  • 附注,但如果您设置 animated:NO 并将其包装在动画块中(例如 UIView withSpring ...),您可以为滚动自定义动画样式/速度。跨度>
  • 请注意,此实现还将调用滚动委托方法,这正是我想要的。谢谢。
  • 这个方案更适合滚动到特定项目。 “setContentOffset”对于简单地滚动到顶部更好更安全。此解决方案需要进行一些检查以避免运行时异常。
【解决方案3】:

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

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

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

self.collectionView.resetScrollPositionToTop()

【讨论】:

    【解决方案4】:

    在斯威夫特中:

    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 将确保表设置回顶部.

    【讨论】:

      【解决方案5】:

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

      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)
          }
      }
      

      【讨论】:

      • 不鼓励仅使用代码的答案。请单击编辑并添加一两段来总结您的代码如何解决问题,或者解释您的答案与以前的答案有何不同。谢谢
      • 这是唯一考虑到 safeAreaInsets 的答案。所有其他答案都滚动到我的 collectionView 的错误位置。
      【解决方案6】:

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

          CGPoint topOffest = CGPointMake(0,-self.collectionView.contentInset.top);
          [self.collectionView setContentOffset:topOffest animated:YES];
      

      【讨论】:

      • 简单干净!
      【解决方案7】:

      抱歉,在撰写本文时我无法发表评论,但我使用的是 UINavigationController 并且 CGPointZero 本身并没有让我达到最高水平,因此我不得不使用以下代码。

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

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

      【讨论】:

        【解决方案8】:

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

        Swift 1.1 代码:

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

        干杯!

        【讨论】:

          【解决方案9】:
          • SWIFT 4.2 解决方案- 假设我有一个 tableView,每个 tableViewCell 都包含一个 Horizo​​ntalCollectionView 由于重复使用单元格,即使第一个 tableViewCell 滚动到第 4 页,向下滚动,其他单元格也设置为第 4 页。

          这在这种情况下有效- 在 tableView 的 cellForRowAt 函数中, let cell = //使用双端队列声明一个单元格 cell.myCollectionView.contentOffset = CGPoint(x:0,y:0)

          【讨论】:

            猜你喜欢
            • 2016-06-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-23
            • 1970-01-01
            相关资源
            最近更新 更多