How to detect when a UIScrollView has completed scrolling in Swift

There was a generally accepted excellent solution to this problem in Obj-C presented by Ashley Smart ( How to determine when a UIScrollView completed scrolling ).

-(void)scrollViewDidScroll:(UIScrollView *)sender { [NSObject cancelPreviousPerformRequestsWithTarget:self]; //ensure that the end of scroll is fired. [self performSelector:@selector(scrollViewDidEndScrollingAnimation:) withObject:nil afterDelay:0.3]; ... } -(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { [NSObject cancelPreviousPerformRequestsWithTarget:self]; ... } 

I need a solution, however, in Swift.

It seems that the best delay function introduced by Matt ( dispatch_after - GCD in swift? ) Will most likely help.

 func delay(delay:Double, closure:()->()) { dispatch_after( dispatch_time( DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)) ), dispatch_get_main_queue(), closure) } 

and implemented as ...

 delay(0.4) { // do stuff } 

but I still haven't put it together. Any help?

+8
source share
5 answers

The delegate method tells you when to finish

 func scrollViewDidEndDecelerating(scrollView: UIScrollView) { self.stoppedScrolling() } func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) { if !decelerate { self.stoppedScrolling() } } func stoppedScrolling() { println("Scroll finished") } 
+16
source

scrollViewDidEndDecelerating will not be called if the user scrolls slowly. Here Ashley Smart asnwear in Swift

 func scrollViewDidScroll(_ scrollView: UIScrollView) { NSObject.cancelPreviousPerformRequests(withTarget: self) perform(#selector(UIScrollViewDelegate.scrollViewDidEndScrollingAnimation), with: nil, afterDelay: 0.3) } func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { NSObject.cancelPreviousPerformRequests(withTarget: self) // Call your function here } 
+7
source

There is a UIScrollViewDelegate method that you can use to detect (or, better say, β€œpredict”) when the scrolling is really complete:

 func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) 

of UIScrollViewDelegate , which can be used to detect (or, better say, "predict") when scrolling is truly complete.

In my case, I used it with horizontal scrolling as follows (in Swift 3 ):

 func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { perform(#selector(self.actionOnFinishedScrolling), with: nil, afterDelay: Double(velocity.x)) } func actionOnFinishedScrolling() { print("scrolling is finished") // do what you need } 
+5
source

You need to check if the user has stopped dragging and if the view continues to slow down after the user has stopped dragging:

 func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if collectionView.isDecelerating == false { // Perform whichever function you desire for when scrolling has stopped } } func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { // Perform whichever function you desire for when scrolling has stopped } 
+1
source

Quick version :

NOTE The answer you mentioned is a possible solution and differs by case

 func scrollViewDidScroll(_ scrollView: UIScrollView) { // YOUR CODE........ NSObject.cancelPreviousPerformRequests(withTarget: self) self.perform(#selector(scrollViewDidEndScrollingAnimation(_:)), with: scrollView, afterDelay: 0.3) } func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { // YOUR CODE ........ NSObject.cancelPreviousPerformRequests(withTarget: self) } 
0
source