web-dev-qa-db-fra.com

Détecter la direction de UIScrollView scroll dans scrollViewWillBeginDragging

J'ai assez cherché sur Google, et j'ai vérifié les posts comme ceux-ci ( Trouver la direction du défilement dans un UIScrollView? ) dans stackoverflow avant de poster ceci. J'ai un nombre dynamique de photos dans une application iPhone, qui s'affiche via UIScrollView. À tout moment, seules 3 photos sont affichées dans la vue par défilement. Quand j'ai, disons 4 photos, au total: 1ère photo: affichée au décalage 0.0 2ème photo: affichée au décalage 320.0 3ème photo: affichée au décalage 640.0

Désormais, lorsque l'utilisateur fait défiler jusqu'à la 4ème photo, la vue par défilement revient à 0,0 offset. Si l'utilisateur essaie de faire défiler "au-delà" de la 4ème photo, le défilement doit s'arrêter dans la direction droite uniquement (pour éviter que l'utilisateur ne défile "au-delà"). Mais actuellement, l'utilisateur 'est capable' de faire défiler au-delà de la dernière photo; Cependant, je le détecte par programme et réinitialise le décalage. Mais cela n’a pas l’air soigné, car l’utilisateur voit momentanément le fond noir. Je veux détecter que l'utilisateur a commencé à faire défiler "à droite" (rappelez-vous, faire défiler "à gauche", c'est-à-dire jusqu'à ce que la photo précédente soit correcte) dans scrollViewWillBeginDragging, afin que je puisse arrêter tout défilement ultérieur vers la droite.

Ce que j'ai essayé:

  1. Essayer d'utiliser self.scrollView.panGestureRecognizer 's translationInView ne fonctionne pas, car aucune instance panGestureRecognizer n'a été renvoyée à la première place (!), Bien que l'API UIScrollView le prétende.
  2. Détecter ceci dans scrollViewDidEndDecelerating est possible, cependant, cela ne me servira à rien.
20
Jean

Merci Kris. C'est ce qui a fonctionné pour moi, enfin:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // Detect the scroll direction
    if (lastContentOffset < (int)scrollView.contentOffset.x) {
    ...
    }
}
6
Jean

Je n'ai eu aucun problème à déterminer la direction dans scrollViewWillBeginDragging lors de la vérification de la panGestureRecognizer de la vue de défilement:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{ 
    CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView.superview];

    if(translation.y > 0)
    {
        // react to dragging down
    } else
    {
        // react to dragging up
    }
}

Je l'ai trouvé très utile pour annuler un parchemin au tout premier mouvement de glisser lorsque l'utilisateur fait glisser dans une direction interdite.

26
mwielbut

Pour Swift 2.0+ et iOS 8.0+

func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
    let actualPosition = scrollView.panGestureRecognizer.translationInView(scrollView.superview)
    if (actualPosition.y > 0){
        // Dragging down 
    }else{
        // Dragging up
    }
}
11
PAC

Solution Swift 3

1- Ajouter UIScrollViewDelegate

2- Ajouter ce code

func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
    let actualPosition = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
    if (actualPosition.y > 0){
        // Dragging down
    }else{
        // Dragging up
    }
}
8
Oscar

C'est ce que j'ai utilisé et cela fonctionne bien au moins sur iOS 6.0:

- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
   CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView];

   // Detect direction by accessing x or y of translation
}

Vous enregistre la variable d'instance pour lastContentOffset ...

5
Michael Thiel

Il semble y avoir des problèmes avec la détection de la direction de défilement basée sur la traduction du reconnaisseur de panoramique de scrollView dans iOS 7+. Cela semble fonctionner assez facilement pour mes besoins

func scrollViewDidScroll(scrollView: UIScrollView) {
    if !scrollDirectionDetermined {
        let translation = scrollView.panGestureRecognizer.translationInView(self.view)
        if translation.y > 0 {
            println("UP")
            scrollDirectionDetermined = true
        }
        else if translation.y < 0 {
            println("DOWN")
            scrollDirectionDetermined = true
        }
    }
}

func scrollViewWillBeginDragging(scrollView: UIScrollView) {
    scrollDirectionDetermined = false
}

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    scrollDirectionDetermined = false
}
1
wfbarksdale

Jetez un coup d'œil à scrollViewWillEndDragging:withVelocity:targetContentOffset:. Vous pouvez utiliser cette méthode pour vérifier si elle va bien là où elle ne devrait pas, puis vous pouvez définir une nouvelle variable targetContentOffset.

Pour la documentation :

Cette méthode n’est pas appelée lorsque la valeur de la propriété pagingEnabled de la vue de défilement est YES. Votre application peut modifier la valeur du paramètre targetContentOffset pour définir l’endroit où la vue de défilement termine son animation de défilement.

0
Kris Gellci

scrollView.panGestureRecognizer translationInView:scrollView ne rapporte rien d’utile dans scrollViewWillBeginDragging dans iOS 7.

Cela fait:

Dans le @interface

BOOL scrollDirectionDetermined;

et:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (!scrollDirectionDetermined) {
        if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x > 0) {
            //scrolling rightwards
        } else {
             //scrolling leftwards
       }
    scrollDirectionDetermined = YES;
    }
}

et:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    scrollDirectionDetermined = NO;
}
0
Richard Maneuv

En vous appuyant sur la réponse de @ Oscar, vous pouvez faire des choses comme 

scrollView.bounces = actualPosition.y < 0 si vous voulez que le scrollView rebondisse lorsque vous faites défiler vers le bas, mais pas lorsque vous faites défiler vers le haut

0
Zack Shapiro