web-dev-qa-db-fra.com

Comment reconnaître le geste de balayage dans UIScrollView

J'essaie de reconnaître le mouvement de balayage gauche/droite dans un UIScrollView. J'ai essayé de créer UISwipeGestureRecognizers et de les associer à la vue de défilement. Cela fonctionne mais très rarement. La plupart du temps, je ne suis pas appelé. Pourquoi?

Comment puis-je obtenir un balayage fiable de gauche à droite pour travailler? Puis-je utiliser les reconnaisseurs de gestes ou dois-je le gérer moi-même d'une manière ou d'une autre dans touchesBegan/Ended

Merci

26
David

Deviner. Dans mon cas, mon UIScrollView contenait un UIImage que j'ai autorisé à zoomer. Apparemment, cela signifiait que le défilement était activé et que UIScrollView avait du mal à faire la distinction entre les gestes destinés à défiler et à glisser (image suivante, précédente).

La clé dans mon cas, est de désactiver le défilement dans la vue de défilement lorsque l'image n'est pas agrandie et de la réactiver lorsqu'elle est agrandie. Cela fournit le comportement attendu.

L'élément critique consiste à mettre ce qui suit dans le délégué de la vue de défilement:

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
  if (scrollView.zoomScale!=1.0) {
    // Zooming, enable scrolling
    scrollView.scrollEnabled = TRUE;
  } else {
    // Not zoomed, disable scrolling so gestures get used instead
    scrollView.scrollEnabled = FALSE;
  }
}

Je dois également initialiser la vue de défilement avec le défilement désactivé. Pour activer le zoom, fournissez simplement une image lors d'un appel de délégué,

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
  // Return the scroll view
  return myImage;
}

Et définissez quelques paramètres dans viewDidLoad pour le zoom et la reconnaissance des gestes de configuration.

- (void)viewDidLoad {
  [super viewDidLoad];
  myScrollView.contentSize = CGSizeMake(myImage.frame.size.width, myImage.frame.size.height);
  myScrollView.maximumZoomScale = 4.0;
  myScrollView.minimumZoomScale = 1.0;
  myScrollView.clipsToBounds = YES;
  myScrollView.delegate = self;

  [myScrollView addSubview:myImage];
  [self setWantsFullScreenLayout:TRUE];

  myScrollView.scrollEnabled = FALSE; 
  UISwipeGestureRecognizer *recognizer = 
    [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
  recognizer.delaysTouchesBegan = TRUE;
  [myScrollView addGestureRecognizer:recognizer];
  [recognizer release];

  recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
  recognizer.direction = UISwipeGestureRecognizerDirectionLeft;
  [myScrollView addGestureRecognizer:recognizer];
  [recognizer release];
  [myScrollView delaysContentTouches];
}
42
David
UIScrollView *scrollView = ...
UISwipeGestureRecognizer *mySwipe = ...

La bonne solution pour résoudre ce problème consiste à ajouter une ligne de code:

[scrollView.panGestureRecognizer requireGestureRecognizerToFail:mySwipe]

Version Swift:

scrollView.panGestureRecognizer.requireGestureRecognizerToFail(mySwipe)

Version Swift4:

scrollView.panGestureRecognizer.require(toFail: mySwipe!);
29
Alexander Volkov

Bon post.

Je faisais une chose similaire (pas de vue d'image) et j'ai essentiellement dû désactiver le défilement si le contentSize était plus petit que la hauteur (ma vue de défilement défile uniquement verticalement).

if (scrollView.contentSize.height>scrollView.frame.size.height) {
    scrollView.scrollEnabled = YES;
}
else {
    scrollView.scrollEnabled = NO;
}

Cela a fait l'affaire pour moi

4
echappy

Pour ceux qui souhaitent animer et personnaliser leurs reconnaisseurs de gestes de balayage.

Nous pouvons utiliser les délégués UIScrollView et UIGestureRecognizer:

 Class ViewController: UIViewController, UISCrollViewDelegate, UIGestureRecognizerDelegate { 


   override func viewDidLoad() {
    super.viewDidLoad()

    scrollView.delegate = self
    swipeLeft.delegate = self
    swipeRight.delegate = self

  }


  func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    return true
  }

  func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
  }

  func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    return scrollView.alwaysBounceHorizontal
  }


  func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

    // Your custom animation at the end of scrolling.
  }
}
1
K4747Z