UICollectionView:如何检测滚动何时停止

Geo*_*old 56 objective-c ios ios6 uicollectionview

我正在使用a UICollectionView快速滚动一组缩略图.滚动结束后,我想显示当前缩略图的更大的高分辨率版本.

如何检测用户何时完成滚动?我确实实现了didEndDisplayingCell,但这只能告诉我特定单元格何时滚动; 它不会告诉我滚动动作何时实际完成.

iDe*_*Dev 117

NS_CLASS_AVAILABLE_IOS(6_0) @interface UICollectionView : UIScrollView
Run Code Online (Sandbox Code Playgroud)

UICollectionView是.的子类UIScrollView.因此,如果您已设置委托并实施UIScrollViewDelegate,您应该能够以相同的方式检测到这一点UIScrollView.

例如: -

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
Run Code Online (Sandbox Code Playgroud)

根据文档,上述方法应该告诉滚动视图何时结束减速滚动运动.

  • 确实,我不明白为什么当前的答案是被接受的,它不起作用`scrollViewDidEndDecelerating`没有被调用但是像D6mi所说的那样,`scrollViewDidEndScrollingAnimation`被调用 (7认同)
  • 辉煌.你不知道这多少讨厌的代码救了我.我试图使用我的UICollectionViewFlowLayout中的shouldInvalidateLayoutForBoundsChange回调来监视它.什么是n00b. (6认同)
  • 请参阅D6mi关于scrollViewDidEndScrollingAnimation的注释.scrollViewDidEndDecelerating没有调用程序化滚动. (2认同)

小智 56

只是为了覆盖你的基础,你应该实现这两个UIScrollViewDelegate方法.在某些情况下,可能没有减速(并且scrollViewDidEndDecelerating不会被调用),例如,页面完全滚动到位.在这种情况下,你的更新就在那里scrollViewDidEndDragging.

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
  if (!decelerate) {
    [self updateStuff];
  }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
  [self updateStuff];
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您分享这一点!这应该是接受的答案b/c OP问"滚动停止" - 如果没有两种方法,用户可以轻松地向下滚动集合视图并释放手指而不会轻弹,并且`scrollViewDidEndDecelerating`将不会被调用,`scrollViewDidEndDragging` .感谢您发布此答案. (7认同)

D6m*_*6mi 31

这里要注意一个重要的事实:

在用户启动的滚动(即平移手势)上调用此方法

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
Run Code Online (Sandbox Code Playgroud)

另一方面,这个人在所有手动(编程)启动的滚动(如scrollRectToVisiblescrollToItemAtIndexPath)上调用

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
Run Code Online (Sandbox Code Playgroud)


Mr *_*nev 9

Swift 3版本:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    // Your code here
}
Run Code Online (Sandbox Code Playgroud)


drp*_*elo 5

Swift 3版本的Abey M和D6mi的答案:

当滚动是由用户操作引起的

public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if (!decelerate) {
        //cause by user
        print("SCROLL scrollViewDidEndDragging")
    }
}

public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    //caused by user
    print("SCROLL scrollViewDidEndDecelerating")
}
Run Code Online (Sandbox Code Playgroud)

当滚动是由代码操作引起的(以编程方式):(例如“ scrollRectToVisible”或“ scrollToItemAtIndexPath”)

public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
    //caused by code
    print("SCROLL scrollViewDidEndScrollingAnimation")
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 将这些函数放入UIScrollViewDelegate或UICollectionViewDelegate委托中。
  • 如果没有单独的委托,请使当前类扩展类文件的UIScrollViewDelegate op顶部

open class MyClass: NSObject , UICollectionViewDelegate
Run Code Online (Sandbox Code Playgroud)

并在您的viewWillAppear中使该类成为其自己的委托

override open func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // ...
    self.myScrollView.delegate = self
    // ...
}
Run Code Online (Sandbox Code Playgroud)