Jak mieć UISwipeGestureRecognizer i UIPanGestureRecognizer działają w tym samym widoku

Jak skonfigurować rozpoznawanie gestów, aby mieć UISwipeGestureRecognizer i UIPanGestureRecognizer działać w tym samym czasie? Takie, że jeśli dotykasz i poruszasz się szybko (szybkie przesunięcie) wykrywa gest jako przesunięcie, ale jeśli dotkniesz, a następnie przenieść (krótkie opóźnienie między dotknięciem i ruchem) wykrywa go jako przesuwanie?

Próbowałem różnych permutacji requireGestureRecognizerToFail i to nie pomogło dokładnie, stało się tak, że jeśli SwipeGesture został pozostawiony, a następnie mój gest pan będzie działać w górę, w dół i w prawo, ale każdy ruch w lewo został wykryty przez gest machnięcia.

Author: Shizam, 2011-02-25

4 answers

Będziesz chciał ustawić jeden z dwóch delegatów UIGestureRecognizer na obiekt, który ma sens (prawdopodobnie self), następnie posłuchaj i zwróć YES dla tej metody :

- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
         shouldRecognizeSimultaneouslyWithGestureRecognizer:
                            (UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

Ta metoda jest wywoływana, gdy rozpoznawanie gestu przez gestureRecognizer lub otherGestureRecognizer zablokuje rozpoznawanie drugiego gestu. Zwrócenie YES jest gwarantowane, aby umożliwić jednoczesne rozpoznawanie; zwracanie NO z drugiej strony nie jest gwarantowane, aby zapobiec jednoczesnemu rozpoznawaniu rozpoznawanie, ponieważ delegat innego rozpoznawacza gestów może zwrócić YES.

 51
Author: Jake Marsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-14 21:16:40

Używanie rozpoznawania panoram do wykrywania przesuwania i panoramowania :

- (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
        }
    }
}
 5
Author: 2cupsOfTech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-07 16:43:02

Domyślnie, gdy użytkownik próbuje przesunąć palcem, gest jest interpretowany jako Panorama. Dzieje się tak dlatego, że gest przesunięcia spełnia warunki konieczne do interpretacji jako pan (ciągły gest), zanim spełni warunki konieczne do interpretacji jako przesunięcie (dyskretny gest).

Musisz wskazać związek między dwoma rozpoznawaczami gestów, wywołując metodę requiragesturerecognizertofail: na rozpoznawaczu gestów, który chcesz opóźnić

[self.panRecognizer requireGestureRecognizerToFail:self.swipeRecognizer];
 4
Author: Evgeny Karpov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-05 21:00:59

Oto pełne rozwiązanie do wykrywania kierunków przesuwania i przesuwania (wykorzystując logikę swipeThreshold firmy 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
        }
    }

}

Użycie:

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

}
 0
Author: Harris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-13 20:00:08