193 votes

Trouver le sens de défilement dans une UIScrollView?

J'ai un UIScrollView avec seulement le défilement horizontal permis, et je voudrais savoir quelle direction (gauche, droite) l'utilisateur fait défiler. Ce que j'ai fait était à la sous-classe de l' UIScrollView et remplacer l' touchesMoved méthode:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];

    UITouch *touch = [touches anyObject];
    float now = [touch locationInView:self].x;
    float before = [touch previousLocationInView:self].x;
    NSLog(@"%f %f", before, now);
    if (now > before){
        right = NO;
        NSLog(@"LEFT");
    }
    else{
        right = YES;
        NSLog(@"RIGHT");

    }

}

Mais cette méthode n'est pas appelée à tous quand je bouge. Qu'en pensez-vous?

399voto

Michael G. Emmons Points 16681

La détermination de la direction est assez simple, mais gardez à l'esprit que le sens peut changer plusieurs fois au cours d'un mouvement. Par exemple, si vous avez un scrollview avec pagination activé et l'utilisateur glisse le doigt pour aller à la page suivante, la direction initiale pourrait être à droite, mais si vous avez rebondir allumé, il sera brièvement aller dans aucun sens du tout, et ensuite brièvement aller vers la gauche.

Pour déterminer la direction, vous aurez besoin d'utiliser l' UIScrollView scrollViewDidScroll délégué. Dans cet exemple, j'ai créé une variable nommée lastContentOffset que j'utilise pour comparer le contenu actuel de décalage avec la précédente. Si il est plus grand, alors la scrollView est de défilement à droite. Si c'est moins la scrollView est de défilement à gauche:

//somewhere in the header
@property (nonatomic, assign) CGFloat lastContentOffset
//
- (void)scrollViewDidScroll:(UIScrollView *)sender 
{
   ScrollDirection scrollDirection;
   if (self.lastContentOffset > scrollView.contentOffset.x)
      scrollDirection = ScrollDirectionRight;
   else if (self.lastContentOffset < scrollView.contentOffset.x) 
      scrollDirection = ScrollDirectionLeft;

   self.lastContentOffset = scrollView.contentOffset.x;

   // do whatever you need to with scrollDirection here.    
}

Je suis l'aide de l'enum ci-dessous pour définir la direction. Le réglage de la première valeur à ScrollDirectionNone a l'avantage de faire en sorte que l'orientation par défaut lors de l'initialisation des variables:

typedef enum ScrollDirection {
    ScrollDirectionNone,
    ScrollDirectionRight,
    ScrollDirectionLeft,
    ScrollDirectionUp,
    ScrollDirectionDown,
    ScrollDirectionCrazy,
} ScrollDirection;

79voto

followben Points 3073

...Je voudrais savoir quelle direction (gauche, droite) l'utilisateur fait défiler.

Dans ce cas, sur iOS 5 et au-dessus, utilisez l' UIScrollViewDelegate afin de déterminer l'orientation de l'utilisateur du poêle geste:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{ 
    if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x > 0) {
        // handle dragging to the right
    } else {
        // handle dragging to the left
    }
}

63voto

Justin Tanner Points 5437

La réponse par Answerbot l'aide d' scrollViewDidScroll est un bon moyen de trouver le sens du courant.

Si vous voulez savoir la direction, seulement après que l'utilisateur a fini de défilement, vous pouvez utiliser ceci:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
  _lastContentOffset = scrollView.contentOffset.x;
}


- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

  if (_lastContentOffset < (int)scrollView.contentOffset.x) {
    // moved right
  }
  else if (_lastContentOffset > (int)scrollView.contentOffset.x) {
    // moved left
  }  
}

8voto

Oded Regev Points 537
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {

    CGPoint targetPoint = *targetContentOffset;
    CGPoint currentPoint = scrollView.contentOffset;

    if (targetPoint.y > currentPoint.y) {
        NSLog(@"up");
    }
    else {
        NSLog(@"down");
    }
}

5voto

xu huanze Points 151

Alternativement, il est possible d'observer le chemin clé "contentOffset". Ceci est utile lorsqu'il n'est pas possible pour vous de régler/modifier le délégué de défilement de la vue.

[yourScrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

Après l'ajout de l'observateur, vous pouvez maintenant:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    CGFloat newOffset = [[change objectForKey:@"new"] CGPointValue].y;
    CGFloat oldOffset = [[change objectForKey:@"old"] CGPointValue].y;
    CGFloat diff = newOffset - oldOffset;
    if (diff < 0 ) { //scrolling down
        // do something
    }
}

Ne pas oublier de supprimer l'observateur en cas de besoin. par exemple, vous pouvez ajouter de l'observateur dans viewWillAppear et de le retirer en viewWillDisappear

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