UIScrollView scrollRectToVisible:animated: is there a way that a method can be called when animation ends
Asked Answered
P

5

13

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

Profundity answered 4/2, 2012 at 10:52 Comment(1)
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. :/Languorous
K
21

Yup use scrollViewDidEndScrollingAnimation

Korella answered 29/8, 2012 at 11:30 Comment(4)
It doesn't get called everytime ex. when scrollRectToVisible() is called inside traitCollationDidChangePatently
This is wrong, there are three separate cases to cover.Languorous
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.Boat
@Languorous Yes, and for some reason SO bot decides to remove 1 reputation from me. Anyway, just wanted to thank you for your answer.Boat
D
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
}];
Deluxe answered 22/10, 2015 at 12:16 Comment(3)
Exactly! I also used the same code only then it worked as per expectation.Sate
I put my cell modification code into the completion but my animation and completion are executing line by line. not working as expected :(Ogg
unfortunately, this will literally crash in many circumstances.Languorous
C
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.

Cloninger answered 19/3, 2013 at 9:13 Comment(1)
for anyone googling here, this very old answer is now incorrect - thanks, Apple! :/Languorous
L
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.

Languorous answered 31/1, 2020 at 15:3 Comment(0)
S
-2

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

Stylist answered 4/2, 2012 at 11:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.