How to know exactly when a UIScrollView's scrolling has stopped?

I found a solution:

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

I did not notice that last bit before, willDecelerate. It is false when the scrollView is stationary when ending the touch. Combined with the above-mentioned speed check, I can snap both when it's slow (and not being touched) or when it's stationary.

For anyone not doing any snapping but needs to know when scrolling stopped, didEndDecelerating will be called at the end of the scroll movement. Combined with a check on willDecelerate in didEndDragging, you'll know when the scrolling has stopped.


[Edited Answer] This is what I use - it handles all the edge cases. You need an ivar to keep state, and as shown in the comments, there are other ways to handle this.

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    //[super scrollViewWillBeginDragging:scrollView];   // pull to refresh

    self.isScrolling = YES;
    NSLog(@"+scrollViewWillBeginDragging");
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    //[super scrollViewDidEndDragging:scrollView willDecelerate:decelerate];    // pull to refresh

    if(!decelerate) {
        self.isScrolling = NO;
    }
    NSLog(@"%@scrollViewDidEndDragging", self.isScrolling ? @"" : @"-");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    self.isScrolling = NO;
    NSLog(@"-scrollViewDidEndDecelerating");
}

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
{   
    self.isScrolling = NO;
    NSLog(@"-scrollViewDidScrollToTop");
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    self.isScrolling = NO;
    NSLog(@"-scrollViewDidEndScrollingAnimation");
}

I created a really simple project uses the above code, so that when a person interacts with a scrollView (including a WebView), it inhibits process intensive work until the user stops interacting with the scrollView AND the scrollview has stopped scrolling. It's like 50 lines of code: ScrollWatcher


Here's how to combine scrollViewDidEndDecelerating and scrollViewDidEndDragging:willDecelerate to perform some operation when scrolling has finished:

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

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

- (void)stoppedScrolling
{
    // done, do whatever
}