iphone - tapgesture recognizer swift
Cómo hacer que un UISwipeGestureRecognizer Y UIPanGestureRecognizer funcionen en la misma vista (4)
Aquí hay una solución completa para detectar direcciones de desplazamiento y desplazamiento (utilizando la lógica swipeThreshold de 2cupsOfTech):
public enum PanSwipeDirection: Int {
case up, down, left, right, upSwipe, downSwipe, leftSwipe, rightSwipe
public var isSwipe: Bool { return [.upSwipe, .downSwipe, .leftSwipe, .rightSwipe].contains(self) }
public var isVertical: Bool { return [.up, .down, .upSwipe, .downSwipe].contains(self) }
public var isHorizontal: Bool { return !isVertical }
}
public extension UIPanGestureRecognizer {
public var direction: PanSwipeDirection? {
let SwipeThreshold: CGFloat = 1000
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 y < -SwipeThreshold ? .upSwipe : .up
case (true, _, let y) where y > 0: return y > SwipeThreshold ? .downSwipe : .down
case (false, let x, _) where x > 0: return x > SwipeThreshold ? .rightSwipe : .right
case (false, let x, _) where x < 0: return x < -SwipeThreshold ? .leftSwipe : .left
default: return nil
}
}
}
Uso:
@IBAction func handlePanOrSwipe(recognizer: UIPanGestureRecognizer) {
if let direction = recognizer.direction {
if direction == .leftSwipe {
//swiped left
} else if direction == .up {
//panned up
} else if direction.isVertical && direction.isSwipe {
//swiped vertically
}
}
}
¿Cómo configurarías los reconocedores de gestos para que puedas tener un trabajo de UISwipeGestureRecognizer y un UIPanGestureRecognizer al mismo tiempo? De modo que si toca y se mueve rápidamente (golpe rápido), detecta el gesto como un golpe, pero si toca y luego se mueve (breve retraso entre toque y movimiento), ¿lo detecta como una bandeja?
He intentado varias permutaciones de requireGestureRecognizerToFail y eso no ayudó exactamente, lo hizo para que, si se dejaba el SwipeGesture, mi gesto de desplazamiento funcionara hacia arriba, hacia abajo y hacia la derecha, pero cualquier movimiento hacia la izquierda fue detectado por el gesto de deslizar.
De forma predeterminada, cuando el usuario intenta deslizar, el gesto se interpreta como una panorámica. Esto se debe a que un gesto de deslizamiento cumple con las condiciones necesarias para ser interpretado como una panorámica (un gesto continuo) antes de que cumpla con las condiciones necesarias para ser interpretado como un deslizamiento (un gesto discreto).
Debe indicar una relación entre dos reconocedores de gestos llamando al método requireGestureRecognizerToFail: en el reconocedor de gestos que desea retrasar
[self.panRecognizer requireGestureRecognizerToFail:self.swipeRecognizer];
Usando un reconocedor de pan para detectar swipping y paneo :
- (void)setupRecognizer
{
UIPanGestureRecognizer* panSwipeRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanSwipe:)];
// Here you can customize for example the minimum and maximum number of fingers required
panSwipeRecognizer.minimumNumberOfTouches = 2;
[targetView addGestureRecognizer:panSwipeRecognizer];
}
#define SWIPE_UP_THRESHOLD -1000.0f
#define SWIPE_DOWN_THRESHOLD 1000.0f
#define SWIPE_LEFT_THRESHOLD -1000.0f
#define SWIPE_RIGHT_THRESHOLD 1000.0f
- (void)handlePanSwipe:(UIPanGestureRecognizer*)recognizer
{
// Get the translation in the view
CGPoint t = [recognizer translationInView:recognizer.view];
[recognizer setTranslation:CGPointZero inView:recognizer.view];
// TODO: Here, you should translate your target view using this translation
someView.center = CGPointMake(someView.center.x + t.x, someView.center.y + t.y);
// But also, detect the swipe gesture
if (recognizer.state == UIGestureRecognizerStateEnded)
{
CGPoint vel = [recognizer velocityInView:recognizer.view];
if (vel.x < SWIPE_LEFT_THRESHOLD)
{
// TODO: Detected a swipe to the left
}
else if (vel.x > SWIPE_RIGHT_THRESHOLD)
{
// TODO: Detected a swipe to the right
}
else if (vel.y < SWIPE_UP_THRESHOLD)
{
// TODO: Detected a swipe up
}
else if (vel.y > SWIPE_DOWN_THRESHOLD)
{
// TODO: Detected a swipe down
}
else
{
// TODO:
// Here, the user lifted the finger/fingers but didn''t swipe.
// If you need you can implement a snapping behaviour, where based on the location of your targetView,
// you focus back on the targetView or on some next view.
// It''s your call
}
}
}
Vas a querer establecer uno de los dos delegados de UIGestureRecognizer
en un objeto que tenga sentido (probablemente self
) luego escuchar y devolver YES
a este method :
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:
(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
Se llama a este método cuando el reconocimiento de un gesto por gestos de reconocimiento u otro gesto de reconocimiento de bloque bloquea al reconocedor de gestos de reconocer su gesto. Tenga en cuenta que devolver YES
está garantizado para permitir el reconocimiento simultáneo; Por otro lado, no se garantiza que el NO
devuelva el reconocimiento simultáneo porque el delegado del otro reconocedor de gestos puede devolver YES
.