2011-03-03 2 views
54

Ok donc j'ai regardé autour de toutes les options sous le soleil pour capturer les gestes multi-touch, et j'ai enfin bouclé le cercle et je suis de retour au UIPanGestureRecognizer.Comment puis-je capturer quelle direction est en train d'être panoramique en utilisant UIPanGestureRecognizer?

La fonctionnalité que je veux est vraiment très simple. J'ai configuré un geste de panoramique à deux doigts, et je veux être capable de mélanger certaines images en fonction du nombre de pixels que je déplace. J'ai tout ce qui va bien, mais je veux être capable de capturer si le geste de panoramique est inversé.

Y a-t-il un moyen intégré que je ne vois pas pour détecter le retour d'un geste? Aurais-je besoin de stocker mon point de départ d'origine, puis suivre le point de fin, puis voir où ils se déplacent après cela et se si c'est moins que le point de fin initial, puis inverser en conséquence? Je peux voir ça fonctionner, mais j'espère qu'il y aura une solution plus élégante !!

Merci

EDIT:

Voici la méthode que l'on reconnaisseur mis à feu. Son un peu un hack, mais il fonctionne:

-(void) throttle:(UIGestureRecognizer *) recognize{ 

throttleCounter ++; 

if(throttleCounter == 6){ 
    throttleCounter = 0; 
    [self nextPic:nil]; 
} 

UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *) recognize; 
UIView *view = recognize.view; 
if(panGesture.state == UIGestureRecognizerStateBegan){ 
    CGPoint translation = [panGesture translationInView:view.superview]; 
    NSLog(@"X: %f, Y:%f", translation.x, translation.y); 
}else if(panGesture.state == UIGestureRecognizerStateEnded){ 
    CGPoint translation = [panGesture translationInView:view.superview]; 
      NSLog(@"X: %f, Y:%f", translation.x, translation.y); 
} 
    } 

Je viens arrivé au point où je vais commencer à essayer de suivre les différences entre les valeurs ... pour essayer de dire de quelle manière ils sont panning

+0

Pouvez-vous poster la mise en œuvre de la méthode que vos feux de pan geste de Recognizer? –

Répondre

161

Sur UIPanGestureRecognizer vous pouvez utiliser -velocityInView: pour obtenir la vélocité des doigts au moment où le geste a été reconnu.

Si vous vouliez faire une chose sur une bonne casserole et une chose sur une casserole à gauche, par exemple, vous pouvez faire quelque chose comme:

- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer 
{ 
    CGPoint velocity = [gestureRecognizer velocityInView:yourView]; 

    if(velocity.x > 0) 
    { 
     NSLog(@"gesture went right"); 
    } 
    else 
    { 
     NSLog(@"gesture went left"); 
    } 
} 

Si vous voulez littéralement détecter une inversion, comme dans vous voulez comparer une nouvelle vitesse à un ancien et voir si elle est juste dans le sens opposé - selon la direction qui peut être - vous pouvez faire:

// assuming lastGestureVelocity is a class variable... 

- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer 
{ 
    CGPoint velocity = [gestureRecognizer velocityInView:yourView]; 

    if(velocity.x*lastGestureVelocity.x + velocity.y*lastGestureVelocity.y > 0) 
    { 
     NSLog(@"gesture went in the same direction"); 
    } 
    else 
    { 
     NSLog(@"gesture went in the opposite direction"); 
    } 

    lastGestureVelocity = velocity; 
} 

la multiplication et ajoutez chose peut sembler un peu étrange. C'est en fait un produit scalaire, mais rassurez-vous, ce sera un nombre positif si les gestes sont dans la même direction, en descendant à 0 s'ils sont exactement à angle droit et en devenant un nombre négatif s'ils sont dans le sens opposé. direction.

+0

Wow! Bien au-delà de l'appel du devoir. Cette réponse est exactement ce dont j'avais besoin !!! Merci Tommmy! –

+0

Juste ce que je cherchais! Merci! :) – Amit

+0

Beaucoup de code! –

7

est ici un outil facile à détecter avant le début du geste de reconnaissance:

public override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { 
    guard let panRecognizer = gestureRecognizer as? UIPanGestureRecognizer else { 
     return super.gestureRecognizerShouldBegin(gestureRecognizer) 
    } 

    // Ensure it's a horizontal drag 
    let velocity = panRecognizer.velocity(in: self) 
    if abs(velocity.y) > abs(velocity.x) { 
     return false 
    } 
    return true 
} 

Si vous voulez un glisser uniquement vertical, vous pouvez changer le x et y.

4

Ce code de Serghei Catraniuc a mieux fonctionné pour moi. https://github.com/serp1412/LazyTransitions

 func addPanGestureRecognizers() { 
     let panGesture = UIPanGestureRecognizer(target: self, action: #selector(respondToSwipeGesture(gesture:))) 
     self.view.addGestureRecognizer(panGesture) 
    } 

    func respondToSwipeGesture(gesture: UIGestureRecognizer){ 
     if let swipeGesture = gesture as? UIPanGestureRecognizer{ 

     switch gesture.state { 
     case .began: 
      print("began") 

     case .ended: 
      print("ended") 
      switch swipeGesture.direction{ 
      case .rightToLeft: 
       print("rightToLeft") 
      case .leftToRight: 
       print("leftToRight") 
      case .topToBottom: 
       print("topToBottom") 
      case .bottomToTop: 
       print("bottomToTop") 
      default: 
       print("default") 
      } 

     default: break 
     } 


    } 
} 

// Extensions

import Foundation 
import UIKit 

public enum UIPanGestureRecognizerDirection { 
    case undefined 
    case bottomToTop 
    case topToBottom 
    case rightToLeft 
    case leftToRight 
} 
public enum TransitionOrientation { 
    case unknown 
    case topToBottom 
    case bottomToTop 
    case leftToRight 
    case rightToLeft 
} 


extension UIPanGestureRecognizer { 
    public var direction: UIPanGestureRecognizerDirection { 
     let velocity = self.velocity(in: view) 
     let isVertical = fabs(velocity.y) > fabs(velocity.x) 

     var direction: UIPanGestureRecognizerDirection 

     if isVertical { 
      direction = velocity.y > 0 ? .topToBottom : .bottomToTop 
     } else { 
      direction = velocity.x > 0 ? .leftToRight : .rightToLeft 
     } 

     return direction 
    } 

    public func isQuickSwipe(for orientation: TransitionOrientation) -> Bool { 
     let velocity = self.velocity(in: view) 
     return isQuickSwipeForVelocity(velocity, for: orientation) 
    } 

    private func isQuickSwipeForVelocity(_ velocity: CGPoint, for orientation: TransitionOrientation) -> Bool { 
     switch orientation { 
     case .unknown : return false 
     case .topToBottom : return velocity.y > 1000 
     case .bottomToTop : return velocity.y < -1000 
     case .leftToRight : return velocity.x > 1000 
     case .rightToLeft : return velocity.x < -1000 
     } 
    } 
} 

extension UIPanGestureRecognizer { 
    typealias GestureHandlingTuple = (gesture: UIPanGestureRecognizer? , handle: (UIPanGestureRecognizer) ->()) 
    fileprivate static var handlers = [GestureHandlingTuple]() 

    public convenience init(gestureHandle: @escaping (UIPanGestureRecognizer) ->()) { 
     self.init() 
     UIPanGestureRecognizer.cleanup() 
     set(gestureHandle: gestureHandle) 
    } 

    public func set(gestureHandle: @escaping (UIPanGestureRecognizer) ->()) { 
     weak var weakSelf = self 
     let tuple = (weakSelf, gestureHandle) 
     UIPanGestureRecognizer.handlers.append(tuple) 
     addTarget(self, action: #selector(handleGesture)) 
    } 

    fileprivate static func cleanup() { 
     handlers = handlers.filter { $0.0?.view != nil } 
    } 

    @objc private func handleGesture(_ gesture: UIPanGestureRecognizer) { 
     let handleTuples = UIPanGestureRecognizer.handlers.filter{ $0.gesture === self } 
     handleTuples.forEach { $0.handle(gesture)} 
    } 
} 

extension UIPanGestureRecognizerDirection { 
    public var orientation: TransitionOrientation { 
     switch self { 
     case .rightToLeft: return .rightToLeft 
     case .leftToRight: return .leftToRight 
     case .bottomToTop: return .bottomToTop 
     case .topToBottom: return .topToBottom 
     default: return .unknown 
     } 
    } 
} 

extension UIPanGestureRecognizerDirection { 
    public var isHorizontal: Bool { 
     switch self { 
     case .rightToLeft, .leftToRight: 
      return true 
     default: 
      return false 
     } 
    } 
} 
Questions connexes