Detección de la dirección del gesto PAN en iOS

En mi aplicación hay una vista de image. Im agregar gesto PAN a esa vista de image.

Esto está funcionando bien.

La vista de la image está en modo horizontal.

Quiero boost un recuento en la label mientras la bandeja del usuario avanza a la derecha y disminuir ese recuento mientras el usuario gira hacia la izquierda.

Busqué en Google mucho, pero no encontré una solución para esto.

¿Alguien puede ayudarme a detectar la dirección en la que el usuario está desplazándose (izquierda / derecha)?

En el selector de destino de su reconocimiento de gestos, use - (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: No conocía este método hasta aproximadamente. 3 minutos antes Uno de los primeros éxitos de Google fue la documentation oficial de Apple.

Algo como esto:

 - (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"); } 

Mi respuesta anterior en 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 } } } 

Reescribir la versión de Adam Waite en 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 } } } 

Aquí hay una versión Swift 3 limpiada, con un ejemplo de uso:

 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 } } } 

Tenga en count que la versión anterior de Adam Swift tiene un error. .Up debería regresar si y <0 y .Down deberían regresar si y> 0 (están invertidos).

Asi que:

 //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 } } }