Reputation: 33644
I have the following code:
UISwipeGestureRecognizer *swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeHighlightReadingVC:)];
swipeGestureRecognizer.delegate = self;
[self.highlightReadingVC_.view addGestureRecognizer:swipeGestureRecognizer];
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHighlightReadingVC:)];
panGestureRecognizer.delegate = self;
[panGestureRecognizer requireGestureRecognizerToFail:swipeGestureRecognizer];
[self.highlightReadingVC_.view addGestureRecognizer:panGestureRecognizer];
My issue is that although I am swiping on the view, it always detects the pan gesture first. I want the swipe to be recognized first before the pan/drag. How do I do that?
Upvotes: 2
Views: 2222
Reputation:
If the goal is to have pan gesture/s prevent recognition of swiping (the usual case):
swipeGesture.requireGestureRecognizerToFail(panGesture)
If the goal is to have swipe gesture/s prevent recognition of panning (the unusual case):
panGesture.requireGestureRecognizerToFail(swipeGesture)
Also do the usual:
panGesture.delegate = self
swipeGesture.delegate = self
And implement shouldRecognizeSimultaneouslyWithGestureRecognizer
to always return true
Note: on things like UIWebView
's and UIScrollView
's to correctly interpret a single-touch swipe, it's best to requireGestureRecognizerToFail
all three (3) of: a pan, a long press and a second swipe recognizer with .numberOfTouchesRequired = 2
for the UX to work intuitively.
Here's what we use (Swift):
class AboutViewController: UIViewController, UIGestureRecognizerDelegate {
@IBOutlet var webView: UIWebView!
var swipeToDismiss: UISwipeGestureRecognizer {
var r = UISwipeGestureRecognizer(target: self, action: "dismiss:")
r.direction = .Right
r.delegate = self
r.requireGestureRecognizerToFail(longPress)
r.requireGestureRecognizerToFail(pan)
r.requireGestureRecognizerToFail(doubleSwipe)
return r
}
var doubleSwipe: UISwipeGestureRecognizer {
var r = UISwipeGestureRecognizer()
r.direction = .Right
r.delegate = self
r.numberOfTouchesRequired = 2
return r
}
var longPress: UILongPressGestureRecognizer {
var r = UILongPressGestureRecognizer()
r.allowableMovement = 4000.0
r.delegate = self
return r
}
var pan: UIPanGestureRecognizer {
var r = UIPanGestureRecognizer()
r.delegate = self
return r
}
func dismiss(recognizer: UISwipeGestureRecognizer!) {
// ...popViewControllerAnimated(true)
}
private func setupWebView() {
// ...
webView.addGestureRecognizer(longPress)
webView.addGestureRecognizer(swipeToDismiss)
webView.addGestureRecognizer(pan)
webView.addGestureRecognizer(doubleSwipe)
}
// MARK: - UIGestureRecognizerDelegate
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
println("gesture start: \(gestureRecognizer)")
return true
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
println("multiple gestures: \(gestureRecognizer), \(otherGestureRecognizer)")
return true
}
// MARK: - UIViewController
override func viewDidLoad() {
super.viewDidLoad()
setupWebView()
}
}
Upvotes: 0
Reputation: 4712
You're going to want to set one of the two UIGestureRecognizer
's delegates to an object that makes sense (likely self
) then listen, and return YES
.
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
This method is called when recognition of a gesture by either gestureRecognizer
or otherGestureRecognizer
would block the other gesture recognizer from recognizing its gesture. Note that returning YES
is guaranteed to allow simultaneous recognition; returning NO
, on the other hand, is not guaranteed to prevent simultaneous recognition because the other gesture recognizer's delegate may return YES
.
I also faced same issue in my app & it works fine for me. So it may solve your problem.
Upvotes: 2