如何使用UIPanGestureRecognizer捕获哪个方向被平移?
好的,我一直在环视太阳下的所有选项来捕捉多点触控手势,最后我来到了UIPanGestureRecognizer。
我想要的function非常简单。 我已经设置了两个手指平移手势,并且我希望能够通过一些图像进行随机移动,具体取决于我移动的像素数。 我有所有的工作好,但我希望能够捕捉如果平移手势是反转。
有没有一个内置的方式,我只是没有看到检测回到一个手势? 我是否需要储存我的原始起点,然后追踪终点,然后看看它们在哪里移动,并确定它是否小于起始终点,然后相应地反转? 我可以看到工作,但我希望有一个更优雅的解决scheme!
谢谢
编辑:
这里是识别器被设置为触发的方法。 它有点黑客,但它的作品:
-(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); } }
我刚刚开始尝试跟踪价值观之间的差异…试图说出他们正在平移的方式
在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; }
乘法和加法的东西可能看起来有点奇怪。 它实际上是一个点积,但是放心,如果手势方向相同,它将是一个正数,如果它们恰好处于正确的angular度,那么它将变为0;如果它们处于相反的方向,则变成负数方向。
在手势识别器开始之前,这是一个简单的检测:
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 }
如果只想垂直拖动,则可以切换x
和y
。
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 } } }