UICollectionView: how to detect when scrolling has

2019-03-08 23:12发布

I'm using a UICollectionView to scroll through a set of thumbnails quickly. Once scrolling ends, I'd like to display a larger hi-res version of the current thumbnail.

How can I detect when the user has completed scrolling? I do implement didEndDisplayingCell, but that only tells me when a particular cell has scrolled off; it doesn't tell me when the scroll motion actually completes.

6条回答
别忘想泡老子
2楼-- · 2019-03-08 23:20

Swift 3 version of Abey M and D6mi 's answers:

When scroll is caused by user action

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

When scroll is caused by code action (programmatically): (like "scrollRectToVisible" or "scrollToItemAtIndexPath")

public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
    //caused by code
    print("SCROLL scrollViewDidEndScrollingAnimation")
}

Notes:

  • Put these functions in your UIScrollViewDelegate or UICollectionViewDelegate delegate.
  • if you don't have a separate delegate, make your current class extend a UIScrollViewDelegate op top of your class file

.

open class MyClass: NSObject , UICollectionViewDelegate

and somewhere in your viewWillAppear make the class its own delegate

override open func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // ...
    self.myScrollView.delegate = self
    // ...
}
查看更多
Juvenile、少年°
3楼-- · 2019-03-08 23:22

Just to cover your bases you should implement both these UIScrollViewDelegate methods. In some cases there may not be a deceleration (and scrollViewDidEndDecelerating would not be called), for e.g., the page is fully scrolled in place. In those case do your update right there in scrollViewDidEndDragging.

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

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
  [self updateStuff];
}
查看更多
虎瘦雄心在
4楼-- · 2019-03-08 23:23

An important fact to note here :

This method gets called on User initiated scrolls (i.e a Pan gesture)

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;

On the other hand, this one gets called on all manually (programatically) initiated scrolls (like scrollRectToVisible or scrollToItemAtIndexPath)

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
查看更多
仙女界的扛把子
5楼-- · 2019-03-08 23:36

if you want to use the visible indexpath:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self scrollingFinish];
}
- (void)scrollingFinish {


    if([self.collectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionHeader]){
        NSIndexPath *firstVisibleIndexPath = [[self.collectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionHeader] firstObject];
        [self.collectionView scrollToItemAtIndexPath:firstVisibleIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
    }
}
查看更多
Summer. ? 凉城
6楼-- · 2019-03-08 23:39
NS_CLASS_AVAILABLE_IOS(6_0) @interface UICollectionView : UIScrollView

UICollectionView is a subclass of UIScrollView. So if you have set the delegate and implemented UIScrollViewDelegate, you should be able to detect this the same way as UIScrollView.

For eg:-

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;

As per documentation, the above method should tell when the scroll view has ended decelerating the scrolling movement.

查看更多
爷的心禁止访问
7楼-- · 2019-03-08 23:44

Swift 3 version:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    // Your code here
}
查看更多
登录 后发表回答