Jordan H
Jordan H

Reputation: 55705

Recognize UISwipeGestureRecognizer with two-finger scroll on trackpad

I have a UISwipeGestureRecognizer added to my view that is recognized when you swipe down with one finger. I want this to also be recognized when you swipe down with two fingers on a trackpad while hovered over this view. Is this possible?

It appears you can make UIPanGestureRecognizer work via a new property allowedScrollTypesMask but I haven't seen something for UISwipeGestureRecognizer.

Upvotes: 1

Views: 924

Answers (1)

Jordan H
Jordan H

Reputation: 55705

While I didn't find a way to do this with UISwipeGestureRecognizer, I solved it by adding a UIPanGestureRecognizer. There's a few things to be aware of.

You need to allow it to be triggered with continuous (trackpad) and discrete (mouse scroll wheel) scrolling:

panGestureRecognizer.allowedScrollTypesMask = [.continuous, .discrete]

To ensure it's only triggered when scrolling down for example, you can implement this delegate method to check which direction they scrolled:

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    if gestureRecognizer == panGestureRecognizer {
        //only support scrolling down to close
        if let view = panGestureRecognizer.view {
            let velocity = panGestureRecognizer.velocity(in: view)
            return velocity.y > velocity.x
        }
    }
    return true
}

One other gotcha, the pan will be triggered when swiping with your finger on the display. You can prevent the pan gesture from being recognized with direct touches so it's only triggered via trackpad/mouse by implementing this other delegate method:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    if gestureRecognizer == panGestureRecognizer {
        return false //disallow touches, only allow trackpad/mouse scroll
    }
    return true
}

Upvotes: 3

Related Questions