【问题标题】:How can I capture which direction is being panned using UIPanGestureRecognizer?如何使用 UIPanGestureRecognizer 捕捉正在平移的方向?
【发布时间】:2011-07-08 10:24:28
【问题描述】:

好的,所以我一直在寻找几乎所有捕捉多点触控手势的选项,我终于绕了一圈,回到了 UIPanGestureRecognizer。

我想要的功能真的很简单。我已经设置了一个两指平移手势,我希望能够根据我移动的像素数量来随机播放一些图像。我已经解决了所有问题,但是如果平移手势被反转,我希望能够捕捉到。

是否有一种我没有看到的内置方式来检测返回手势?我是否必须存储我的原始起点,然后跟踪终点,然后查看它们之后的移动位置,并确定它是否小于初始终点,然后相应地反转?我可以看到这个工作,但我希望有一个更优雅的解决方案!

谢谢

编辑:

这是识别器被设置为触发的方法。它有点破解,但它的工作原理:

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

我已经到了要开始尝试跟踪值之间的差异的地步……尝试判断它们的平移方式

【问题讨论】:

  • 你能发布你的平移手势识别器触发的方法的实现吗?

标签: iphone capture reverse uigesturerecognizer pan


【解决方案1】:

在 UIPanGestureRecognizer 上,您可以使用 -velocityInView: 获取识别手势时手指的速度。

如果您想在右侧平底锅上做一件事,在左侧平底锅上做一件事,例如,您可以执行以下操作:

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

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

如果您确实想检测反转,例如您想将新速度与旧速度进行比较,看看它是否正好在相反的方向(无论是哪个方向),您可以这样做:

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

乘法和加法可能看起来有点奇怪。它实际上是一个点积,但请放心,如果手势在同一方向上,它将是一个正数,如果它们完全成直角则下降到 0,然后如果它们在相反方向上,则变为负数方向。

【讨论】:

  • 哇!远远超出职责范围。这个答案正是我需要的!!!谢谢汤米!
  • 正是我想要的!谢谢! :)
【解决方案2】:

以下是在手势识别器开始之前很容易检测到的:

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
}

如果你只想垂直拖动,你可以切换xy

【讨论】:

    【解决方案3】:

    Serghei Catraniuc 的这段代码对我来说效果更好。 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
            }
    
    
        }
    }
    

    // 扩展

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-13
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-30
      • 2011-04-03
      • 2015-02-16
      相关资源
      最近更新 更多