Search code examples
iosswiftuiscrollview

How to detect when a UIScrollView has finished scrolling In Swift


There was, by all accounts, an excellent solution to this problem in Obj-C presented by Ashley Smart (How to detect when a UIScrollView has finished 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 appears that the excellent delay function, contributed by Matt (dispatch_after - GCD in swift?) is likely to 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've still not put it together. Any help?


Solution

  • The delegate method tells you when finished

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