171 votes

Comment détecter la fin du défilement d'un UIScrollView ?

UIScrollViewDelegate a deux méthodes de délégué scrollViewDidScroll: y scrollViewDidEndScrollingAnimation: mais aucun d'entre eux ne vous indique quand le défilement est terminé. scrollViewDidScroll vous informe seulement que la vue défilante a défilé et non qu'elle a fini de défiler.

L'autre méthode scrollViewDidEndScrollingAnimation ne semble se déclencher que si vous déplacez la vue de défilement de manière programmatique, et non si l'utilisateur fait défiler la vue.

Quelqu'un connaît-il un système permettant de détecter quand une vue défilante a terminé son défilement ?

0 votes

Voir aussi, si vous voulez détecter un défilement terminé après un défilement programmé : stackoverflow.com/questions/2358046/

0 votes

183voto

Ashley Smart Points 912

Le site 320 mises en œuvre sont tellement mieux - voici un patch pour obtenir un début et une fin de défilement cohérents.

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

...
}

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
...
}

0 votes

La seule réponse utile au SO pour mon problème de défilement. Merci !

0 votes

Merci. C'est suuuuuperb réponse :)

4 votes

Devrait être [self performSelector:@selector(scrollViewDidEndScrollingAnimation :) withObject:sender afterDelay:0.3]

175voto

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

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

- (void)stoppedScrolling {
    // ...
}

15 votes

Il semble que cela ne fonctionne que si l'on décélère. Si vous effectuez un panoramique lent, puis le relâchez, il n'appelle pas didEndDecelerating.

5 votes

Bien que ce soit l'API officielle. En fait, elle ne fonctionne pas toujours comme on l'attend. @Ashley Smart a donné une solution plus pratique.

0 votes

Fonctionne parfaitement et l'explication est logique

23voto

lwburk Points 29313

Cette méthode a été décrite dans d'autres réponses, mais voici (en code) comment la combiner scrollViewDidEndDecelerating y scrollViewDidEndDragging:willDecelerate pour effectuer une opération lorsque le défilement est terminé :

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

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

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

21voto

Aurelien Porte Points 824

Pour tous les parchemins liés aux interactions de dragage, cela sera suffisant :

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    _isScrolling = NO;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    if (!decelerate) {
        _isScrolling = NO;
    }
}

Maintenant, si votre défilement est dû à un setContentOffset/scrollRectVisible programmatique (avec le paramètre animated = OUI ou vous savez évidemment quand le scroll est terminé) :

 - (void)scrollViewDidEndScrollingAnimation {
     _isScrolling = NO;
}

Si votre défilement est dû à quelque chose d'autre (comme l'ouverture ou la fermeture du clavier), il semble que vous devrez détecter l'événement avec un hack car scrollViewDidEndScrollingAnimation n'est pas non plus utile.

Le cas d'un PAGINÉ vue défilante :

Parce que, je suppose, qu'Apple applique une courbe d'accélération, scrollViewDidEndDecelerating sont appelés pour chaque drag, il n'y a donc pas besoin d'utiliser scrollViewDidEndDragging dans ce cas.

0 votes

Votre vue de défilement paginé a un problème : si vous relâchez le défilement exactement à la position de fin de page (quand aucun défilement n'est nécessaire), scrollViewDidEndDecelerating ne sera pas appelé

20voto

texmex5 Points 3187

Je pense que scrollViewDidEndDecelerating est celui que vous voulez. C'est une méthode optionnelle de UIScrollViewDelegates :

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

Indique au délégué que la vue de défilement a terminé de décélérer le mouvement de défilement.

Documentation sur le UIScrollViewDelegate

0 votes

Er, j'ai donné la même réponse. :)

0 votes

Doh. Le nom est un peu cryptique mais c'est exactement ce que je cherchais. J'aurais dû mieux lire la documentation. C'était une longue journée...

0 votes

Cette phrase a résolu mon problème. Une solution rapide pour moi ! Merci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X