Détection de la direction du geste PAN dans iOS

Dans mon application, il y a une vue d'image. Im append PAN geste à cette vue de l'image.

Cela fonctionne bien.

La vue de l'image est en mode paysage.

Je veux augmenter le nombre d'labels pendant que l'user effectue un panoramique vers la bonne direction et diminue ce nombre pendant que l'user effectue un panoramique vers la gauche.

J'ai beaucoup googlé mais je n'ai pas trouvé de solution pour ça.

Quelqu'un peut-il m'aider s'il vous plaît comment détecter la direction dans laquelle l'user est panoramique (gauche / droite)?

Dans le sélecteur de cible de votre reconnaissance de - (CGPoint)velocityInView:(UIView *)view; , utilisez la vue - (CGPoint)velocityInView:(UIView *)view; :

 - (void)panRecognized:(UIPanGestureRecognizer *)rec { CGPoint vel = [rec velocityInView:self.view]; if (vel.x > 0) { // user dragged towards the right counter++; } else { // user dragged towards the left counter--; } } 

Ps: Je ne savais pas à propos de cette méthode jusqu'à env. 3 minutes avant. L'un des premiers résultats de Google était la documentation officielle d'Apple.

Quelque chose comme ça:

 - (void)pan:(UIPanGestureRecognizer *)sender { typedef NS_ENUM(NSUInteger, UIPanGestureRecognizerDirection) { UIPanGestureRecognizerDirectionUndefined, UIPanGestureRecognizerDirectionUp, UIPanGestureRecognizerDirectionDown, UIPanGestureRecognizerDirectionLeft, UIPanGestureRecognizerDirectionRight }; static UIPanGestureRecognizerDirection direction = UIPanGestureRecognizerDirectionUndefined; switch (sender.state) { case UIGestureRecognizerStateBegan: { if (direction == UIPanGestureRecognizerDirectionUndefined) { CGPoint velocity = [sender velocityInView:recognizer.view]; BOOL isVerticalGesture = fabs(velocity.y) > fabs(velocity.x); if (isVerticalGesture) { if (velocity.y > 0) { direction = UIPanGestureRecognizerDirectionDown; } else { direction = UIPanGestureRecognizerDirectionUp; } } else { if (velocity.x > 0) { direction = UIPanGestureRecognizerDirectionRight; } else { direction = UIPanGestureRecognizerDirectionLeft; } } } break; } case UIGestureRecognizerStateChanged: { switch (direction) { case UIPanGestureRecognizerDirectionUp: { [self handleUpwardsGesture:sender]; break; } case UIPanGestureRecognizerDirectionDown: { [self handleDownwardsGesture:sender]; break; } case UIPanGestureRecognizerDirectionLeft: { [self handleLeftGesture:sender]; break; } case UIPanGestureRecognizerDirectionRight: { [self handleRightGesture:sender]; break; } default: { break; } } } case UIGestureRecognizerStateEnded: { direction = UIPanGestureRecognizerDirectionUndefined; break; } default: break; } } - (void)handleUpwardsGesture:(UIPanGestureRecognizer *)sender { NSLog(@"Up"); } - (void)handleDownwardsGesture:(UIPanGestureRecognizer *)sender { NSLog(@"Down"); } - (void)handleLeftGesture:(UIPanGestureRecognizer *)sender { NSLog(@"Left"); } - (void)handleRightGesture:(UIPanGestureRecognizer *)sender { NSLog(@"Right"); } 

Ma réponse précédente dans Swift

 public enum Direction: Int { case Up case Down case Left case Right public var isX: Bool { return self == .Left || self == .Right } public var isY: Bool { return !isX } } public extension UIPanGestureRecognizer { public var direction: Direction? { let velocity = velocityInView(view) let vertical = fabs(velocity.y) > fabs(velocity.x) switch (vertical, velocity.x, velocity.y) { case (true, _, let y) where y < 0: return .Up case (true, _, let y) where y > 0: return .Down case (false, let x, _) where x > 0: return .Right case (false, let x, _) where x < 0: return .Left default: return nil } } } 

Voici une version nettoyée de Swift 3, avec exemple d'utilisation:

 public enum PanDirection: Int { case up, down, left, right public var isVertical: Bool { return [.up, .down].contains(self) } public var isHorizontal: Bool { return !isVertical } } public extension UIPanGestureRecognizer { public var direction: PanDirection? { let velocity = self.velocity(in: view) let isVertical = fabs(velocity.y) > fabs(velocity.x) switch (isVertical, velocity.x, velocity.y) { case (true, _, let y) where y < 0: return .up case (true, _, let y) where y > 0: return .down case (false, let x, _) where x > 0: return .right case (false, let x, _) where x < 0: return .left default: return nil } } @IBAction func handlePanView(recognizer: UIPanGestureRecognizer) { if let direction = recognizer.direction { if direction.isVertical { //do what you want when pan is vertical } else if direction == .left { //do what you want when pan is left } } } 

Réécrivez la version d'Adam Waite sur Swift 3

 public enum PanDirection: Int { case up, down, left, right public var isX: Bool { return self == .left || self == .right } public var isY: Bool { return !isX } } extension UIPanGestureRecognizer { var direction: PanDirection? { let velocity = self.velocity(in: view) let vertical = fabs(velocity.y) > fabs(velocity.x) switch (vertical, velocity.x, velocity.y) { case (true, _, let y): return y < 0 ? .up : .down case (false, let x, _): return x > 0 ? .right : .left } } } 

Notez que la version d'Adam Swift ci-dessus a une erreur. .Up devrait returnner si y <0 et .Down devrait returnner si y> 0 (ils sont inversés).

Alors:

 //MARK: - Direction internal enum Direction { case Up case Down case Left case Right } //MARK: - UIPanGestureRecognizer internal extension UIPanGestureRecognizer { internal var direction: Direction? { let velocity = velocityInView(view) let isVertical = fabs(velocity.y) > fabs(velocity.x) switch (isVertical, velocity.x, velocity.y) { case (true, _, let y) where y < 0: return .Up case (true, _, let y) where y > 0: return .Down case (false, let x, _) where x > 0: return .Right case (false, let x, _) where x < 0: return .Left default: return nil } } }