13

Is there a way to know when the animation has end and uiscrollview has come to rest.

  • Regarding this very old question, nowadays there are THREE situations which must be covered. It's one of the strangest and most difficult issues in iOS. :/ – Fattie Jan 31 '20 at 15:03

5 Answers5

21

Yup use scrollViewDidEndScrollingAnimation

Yogesh Agarwal
  • 2,610
  • 3
  • 27
  • 31
  • 1
    It doesn't get called everytime ex. when scrollRectToVisible() is called inside traitCollationDidChange – Michał Ziobro Oct 04 '18 at 17:40
  • 1
    This is wrong, there are three separate cases to cover. – Fattie Jan 31 '20 at 15:00
  • I agree with @Fattie's comment because there are multiple scenarios which scrolling can end. This answer is not as good as Fattie's answer below. – Michael Sep 07 '22 at 08:16
  • @Fattie Yes, and for some reason SO bot decides to remove 1 reputation from me. Anyway, just wanted to thank you for your answer. – Michael Sep 07 '22 at 16:37
13

I do it like this because sometimes using the delegate isn't practical for me, like if i'm doing it in UIViewController transition:

[UIView animateWithDuration:0.3 animations:^{
    [scrollView setContentOffset:CGPointMake(0, -scrollView.contentInset.top) animated:NO];
} completion:^(BOOL finished) {
    // This is called when it's complete
}];
bandejapaisa
  • 26,576
  • 13
  • 94
  • 112
5

Implement UIScrollViewDelegate delegate methods for your UIScrollView the following way:

Use scrollViewDidEndScrollingAnimation: to detect when the scrolling animation concludes when you've initiated the scrolling by calling setContentOffset:animated: or scrollRectToVisible:animated: methods (with animated:YES).

If you want to monitor scroll view motion that's been initiated by touch gestures, use scrollViewDidEndDecelerating: method, which is called when the scrolling movement comes to a halt.

Markus Rautopuro
  • 7,997
  • 6
  • 47
  • 60
3

You need to cover THREE (!) cases. Thanks, Apple.

// do note that you need all three of the following

public func scrollViewDidEndScrollingAnimation(_ s: UIScrollView) {
    // covers case setContentOffset/scrollRectToVisible
    fingerOrProgrammaticMoveDone()
}

public func scrollViewDidEndDragging(_ s: UIScrollView, willDecelerate d: Bool) {
    if decelerate == false {
        // covers certain cases of user finger
        fingerOrProgrammaticMoveDone()
    }
}

public func scrollViewDidEndDecelerating(_ s: UIScrollView) {
    // covers certain cases of user finger
    fingerOrProgrammaticMoveDone()
}

(Be careful to not forget the extra "if" clause in the middle one.)

Then in fingerOrProgrammaticMoveDone() , do what you need.

A good example of this is the nightmare of handling paged scrolling. It is very, very hared to know what page you are on.

Community
  • 1
  • 1
Fattie
  • 27,874
  • 70
  • 431
  • 719
-2

scrollViewDidEndDecelerating: UIScrollView delegate method is called when scrollView stops completely.

Kyr Dunenkoff
  • 8,090
  • 3
  • 23
  • 21