Hi any one can explain me, what are the cases can i use the following UIGestureRecognizer Methods.
1. - (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer*)preventingGestureRecognizer
- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer
2. - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer
3. - (BOOL)shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer
- (BOOL)shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer
Kindly give the use case of all this three methods, if u have any example kindly comment here.
Thanks in advance.
Please read the Apple's Documentation.
canBePreventedByGestureRecognizer:
Overridden to indicate that the specified gesture recognizer can prevent the receiver from recognizing a gesture.
canPreventGestureRecognizer:
Overridden to indicate that the receiver can prevent the specified gesture recognizer from recognizing its gesture.
requireGestureRecognizerToFail:
Creates a dependency relationship between the receiver and another gesture recognizer.
shouldBeRequiredToFailByGestureRecognizer:
Overridden to indicate that the receiver should be required to fail by the specified gesture recognizer.
shouldRequireFailureOfGestureRecognizer:
Overridden to indicate that the receiver requires the specified gesture recognizer to fail.
All those methods simply establish dependancies of different types between different recognizers. Certain gesture recognizers may use similar gestures, and these are typically set up so that one takes precedence over another.
For example, a scrolling gesture and a swipe gesture are similar in that they both involve a touch moving in a particular direction, so you might set up the swipe recognizer such that it requires the scrolling recognizer to fail before the swipe can be recognized. Or, you could set them up so that the scrolling recognizer prevents the swipe recognizer from being activated while the user is scrolling.
Related
In the doc Coordinating Multiple Gesture Recognizers, it says:
UIKit normally allows the recognition of only one gesture at a time on
a single view. ... For example, in a view that contains both pan and swipe gesture recognizers, swipes are never recognized.
With that being said, there are also some exceptions. For example, in a view with two UITapGestureRecognizers, the actions of both will get fired.
There's the UIGestureRecognizerDelegate method gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) comes into play externally. But how can the system built-in gesture recognizers, such as UITapGestureRecognizer, decide internally whether or not to work with other recognizers? Or, is there any difference between continuous gesture recognizers and discrete gesture recognizers as regards the behavior?
There are two interesting methods of UIGestureRecognizer in the decision process, in which gesture recognizers may be "prevented":
canPrevent(_:)
canBePrevented(by:)
By debugging subclasses of UITapGestureRecognizer, UISwipeGestureRecognizer and UIPanGestureRecognizer, I found that:
A "double tap" recognizer will prevent a "single tap" recognizer, but NOT vice versa
A pan recognizer will prevent a swipe recognizer
When there are multiple gesture recognizers, the first one that recognizes its gesture will render other recognizers into .failed, by default.
That explains the observed behavior.
I have found no way in the documentation on how to specify the number of touches for UIPinchGestureRecognizer or UIRotationGestureRecognizer.
All I found anywhere is that it only works with two fingers, but by my experiments, it also works with 3 or even more fingers.
Furthermore in the action the property numberOfTouches also never returns the actual number of fingers.
I want to limit it only for two fingers because it gets all confused with other 3-finger recognizers.
Could you, please, suggest me a good way to do that? Thanks.
According to the docs UIPinchGestureRecognizer handles
[...] pinching gestures involving two touches [...]
Apparently it only considers two touches but allows additional touches to happen concurrently.
To answer your question: you can try to get the actual number of touches by other means and prevent the pinch action when that count is larger than 2. One way is to add more gesture recognizers which handle gestures on the same view (e.g. multiple UITapGestureRecognizers, one for each possible number of touches); another one is to override touchesBegan and touchesMoved of the view your gesture recognizer is installed on and use the count of the provided touches array.
(I'd go with the second approach first because managing multiple gesture recognizers in parallel can get problematic.)
Add a delegate to the pinch gesture recogniser you're concerned about.
Implement gestureRecognizer(_:, shouldRecognizeSimultaneouslyWith:) and return false if you want the pinch gesture to be ignored if there is another recogniser also in progress.
I found when I have UIGesture, like UITapGesture, it always take precedence over the touchbegan methods etc.
Reading books, If setting "Delayed Begin", this should be true. But I don't set the "Delayed Begin"?
By default, touchesBegan: is delivered both to the gesture recognizer and to the view. It isn't touchesBegan: that is delayed by default - it's touchesEnded:, meaning that the gesture recognizer holds onto this until it can decide whether to recognize its gesture or not (and this is especially important for a multitap gesture, because the first touch may end but the gesture might still recognize if there's a further tap).
I'm using a UIGestureRecognizer to recognize a single tap, a double tap and a longpress.
What I would like to do is also recognize a longpress, then swipe to either left or right.
Would this be possible given that I'm already consuming a longpress? I'm confused on this one and would appreciate pointers on how to do.
Thanks
Just tried this out myself and it seems as if the UILongPressGestureRecognizer will transition to its end state as soon as the UISwipeGestureRecognizer begins. Just make sure shouldRecognizeSimultaneouslyWithGestureRecognizer: returns YES for this gesture combination.
You'd need to use two gesture recognisers and make sure you track the state of the long press one when you receive a callback to say it's ended, and then do something based on the swipe/pan gesture following it.
I am developing a app in which I have a view which contains subView in it.
I want to track both swipe and tap actions such as a single click.
Actions should be tracked only when the user touches within my subview. When the user taps I want to perform one action, when the user swipes I want perform another.
For tracking the swipe, I implemented UIGestureRecognizer and it is working fine. But I don't know how to track the tap option. Please guide me how to achieve this.
The main thing is, when I tap it should call tap action only and vice versa.
You can use UITapGestureRecognizer for tap gestures.
"UITapGestureRecognizer is a concrete subclass of UIGestureRecognizer
that looks for single or multiple taps. For the gesture to be
recognized, the specified number of fingers must tap the view a
specified number of times."
This method includes the numberOfTapsRequired ("The number of taps for the gesture to be recognized.") and numberOfTouchesRequired ("The number of fingers required to tap for the gesture to be recognized") properties where you can set exactly how you want it to react to user action.
In this case, as you only want it to be activated when tapped once, the default settings for both these properties (both have default values of 1) should be fine.
The best place to get the information is Defining How Gesture Recognizers Interact of Event Handling Guide for iOS
When a view has multiple gesture recognizers attached to it, you may
want to alter how the competing gesture recognizers receive and
analyze touch events. By default, there is no set order for which
gesture recognizers receive a touch first, and for this reason touches
can be passed to gesture recognizers in a different order each time.
You can override this default behavior to:
Specify that one gesture recognizer should analyze a touch before another gesture recognizer.
Allow two gesture recognizers to operate simultaneously.
Prevent a gesture recognizer from analyzing a touch.