uswipegesturerecogizer只有一个方向工作



所以我用pageControl制作一个页面(这是一个带有多个视图的页面,带点指示您所在的页面),我的代码看起来像以下viewDidLoad:

UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];
UIView *temp = [[UIView alloc]initWithFrame:self.view.frame];
temp.backgroundColor = [UIColor clearColor];
[temp addGestureRecognizer:swipe];
[self.view addSubview:temp];

在swipeAction选择器中我有:

- (void)swipeAction: (UISwipeGestureRecognizer *)sender{
    NSLog(@"Swipe action called");
    if (sender.direction == UISwipeGestureRecognizerDirectionLeft) {
        //Do Something
    }
    else if (sender.direction == UISwipeGestureRecognizerDirectionRight){
        //Do Something Else
    }
}

令我惊讶的是,这个方法只在你向右滑动时起作用(即else if块被调用)。当你向左滑动时,swipeAction甚至没有被调用!这很奇怪,为什么会发生这种情况,我应该如何修改我的代码?任何回复都是感激的。非常感谢!

这里有几件事您应该注意。首先,你必须为你想要观察的每个方向创建一个手势。这不是什么大问题,因为你可以简单地给它们相同的选择器,它就像一个手势指向两个方向。

UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];
leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft;
UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];
rightSwipe.direction = UISwipeGestureRecognizerDirectionRight;

UIView *temp = [[UIView alloc]initWithFrame:self.view.frame];
temp.backgroundColor = [UIColor clearColor];
[temp addGestureRecognizer:leftSwipe];
[temp addGestureRecognizer:rightSwipe];
[self.view addSubview:temp];

第二,你没有指定手势的方向,让它默认为右(或方向枚举中的1)

来自文档:

默认方向是uswipegesturerecognizerdirectionright。有关更多信息,请参阅iswipegesturerecognizerdirection常量的描述。

typedef enum {
   UISwipeGestureRecognizerDirectionRight = 1 << 0,
   UISwipeGestureRecognizerDirectionLeft  = 1 << 1,
   UISwipeGestureRecognizerDirectionUp    = 1 << 2,
   UISwipeGestureRecognizerDirectionDown  = 1 << 3
} UISwipeGestureRecognizerDirection;

Swift 4

let swiper = UISwipeGestureRecognizer(target: self, action: #selector(self.swipeFunction(sender:)))
swiper.direction = UISwipeGestureRecognizer.Direction.right
let swipel = UISwipeGestureRecognizer(target: self, action: #selector(self.swipeFunction(sender:)))
swipel.direction = UISwipeGestureRecognizer.Direction.left
UIView().addGestureRecognizer(swiper)
UIView().addGestureRecognizer(swipel)
@objc func swipeFunction(sender: UISwipeGestureRecognizer) {
    print(sender)
}

你应该能够从那里找出它,你为每个方向添加一个uswipegesturerecognizer到UIView

滑动。方向设置你正在识别的方向,它不会告诉你哪个方向被滑动。在创建识别器时添加这一行:

swipe.direction = UISwipeGestureRecognizerDirectionLeft|UISwipeGestureRecognizerDirectionRight;

如果您需要检测哪个方向被滑动,只需使用两个不同的识别器,一个用于左,一个用于右。

我面临着同样的问题,并找到了一种方法,通过扩展UIPanGestureRecognizer来实现UIDirectionalSwipeGestureRecognizer,如下所示。滑动的direction可以作为识别器实例的公共属性使用:

import UIKit
public final class UIDirectionalSwipeGestureRecognizer: UIPanGestureRecognizer {
    
    public private(set) var direction: UISwipeGestureRecognizer.Direction?
    
    public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesBegan(touches, with: event)
        
        direction = nil
        
        if let touch = touches.first {
            startTimestamp = touch.timestamp
            startLocation = touch.location(in: nil)
        }
    }
    
    public override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesMoved(touches, with: event)
        
        if
            let currentTimestamp = touches.first?.timestamp,
            let startTimestamp = startTimestamp,
            currentTimestamp - startTimestamp > 0.3
        {
            touchesCancelled(touches, with: event)
        }
    }
    
    public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesEnded(touches, with: event)
        
        if
            let endLocation = touches.first?.location(in: nil),
            let startLocation = startLocation,
            startLocation.distance(to: endLocation) > 20
        {
            direction = UISwipeGestureRecognizer.Direction.fromPoint(startLocation, to: endLocation)
        }
    }
    
    // MARK: - Private
    
    private var startTimestamp: TimeInterval?
    private var startLocation: CGPoint?
}
// MARK: - Extensions
public extension CGPoint {
    
    func distanceSquared(to: CGPoint) -> CGFloat {
        (to.x - x) * (to.x - x) + (to.y - y) * (to.y - y)
    }
    
    func distance(to: CGPoint) -> CGFloat {
        sqrt(distanceSquared(to: to))
    }
}
extension UISwipeGestureRecognizer.Direction {
    
    public static func fromPoint(_ startPoint: CGPoint, to endPoint: CGPoint) -> Self {
        let offset = CGSize(width: endPoint.x - startPoint.x, height: endPoint.y - startPoint.y)
        
        if abs(offset.width) > abs(offset.height) {
            return offset.width > 0 ? .right : .left
        } else {
            return offset.height > 0 ? .up : .down
        }
    }
}

最新更新