2011-03-03 6 views
54

Okej, więc rozglądałem się w niemal każdej opcji pod słońcem, aby uchwycić gesty wielodotykowe, a nareszcie zatoczyłem pełne koło i wróciłem do UIPanGestureRecognizer.Jak mogę uchwycić, który kierunek jest przesuwany za pomocą narzędzia UIPanGestureRecognizer?

Funkcjonalność, której chcę, jest naprawdę prosta. Ustawiłem gest przesuwania dwoma palcami i chcę móc przetasować niektóre obrazy w zależności od tego, ile pikseli się poruszam. Mam wszystko, co się udało, ale chcę być w stanie uchwycić, jeśli gest panoramy jest ODWRÓCONY.

Czy jest zbudowany w taki sposób, że po prostu nie widzę, aby wykryć cofanie się w geście? Czy musiałbym przechowywać mój początkowy punkt początkowy, a następnie śledzić punkt końcowy, a następnie zobaczyć, gdzie się poruszają po tym i se, jeśli jest on mniejszy niż początkowy punkt końcowy, a następnie odwrotnie? Widzę, że działa, ale mam nadzieję, że istnieje bardziej eleganckie rozwiązanie!

Dzięki

EDIT:

Oto metoda rozpoznawania, że ​​jest ustawiony na ogień. Jego nieco hack, ale działa:

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

Właśnie dostał się do punktu, w którym mam zamiar rozpocząć próby do śledzenia różnic między wartościami ... spróbować i powiedzieć, w jaki sposób są one przesuwanie

+0

można zakładać realizację metody że twój pan pożary gest Rozpoznawanie? –

Odpowiedz

161

W usłudze UIPanGestureRecognizer można użyć wartości -velocityInView:, aby uzyskać prędkość palców w momencie rozpoznania gestu.

Jeśli chciał zrobić jedną rzecz na patelni prawej i jedno na patelni w lewo, na przykład, można zrobić coś takiego:

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

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

Jeśli dosłownie chcą wykryć odwrócenie, podobnie jak w chcesz porównać nową prędkość do starego i sprawdzić, czy jest to tylko w przeciwnym kierunku - w zależności od tego kierunku, który może być - można zrobić:

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

wielowarstwowego i dodać coś może wyglądać trochę dziwnie. W rzeczywistości jest to produkt kropkowany, ale zapewniamy, że będzie to liczba dodatnia, jeśli gesty są w tym samym kierunku, zejście do zera, jeśli są one dokładnie ustawione pod kątem prostym, a następnie stają się liczbą ujemną, jeśli znajdują się w przeciwnym kierunku. kierunek.

+0

Wow! Sposób ponad i poza obowiązkiem. Ta odpowiedź jest dokładnie tym, czego potrzebowałem !!! Dzięki Tommmy! –

+0

Właśnie tego szukałem! Dzięki! :) – Amit

+0

Świetny kawałek kodu! –

7

Oto prosty do wykrycia przed rozpoczęciem rozpoznawania gest:

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 
} 

Jeśli chcesz pionową tylko opór, można przełączyć x i y.

4

Ten kod z Serghei Catraniuc sprawdził się lepiej. 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 
     } 
    } 
} 
Powiązane problemy