feat: cancel contradictory gesture events#7296
feat: cancel contradictory gesture events#7296MartoYankov merged 14 commits intoNativeScript:masterfrom MCurran16:gestures-fix
Conversation
… gestures-fix * 'gestures-fix' of github.com:MCurran16/NativeScript: Reset tns-<android/ios> for test app refact(iOS): code convention for iOS gestures fix(gestures-android): Handle tap and double tap listeners on the same target Fix simultaneous tap gestures for iOS # Conflicts: # tns-core-modules/ui/gestures/gestures.android.ts
|
Also, I think this should be considered as behavior breaking change. |
…st event up and second event on down
| // If both gesture recognizers are of type UITapGestureRecognizer, do not allow | ||
| // simultaneous recognition. | ||
| if (gestureRecognizer instanceof UITapGestureRecognizer && otherGestureRecognizer instanceof UITapGestureRecognizer) { | ||
| return false; |
There was a problem hiding this comment.
I imagine this is going to change the behavior where a tap was recognized by both parent and child. This change makes it so only one tap gesture is recognized on iOS, but seems to be unchanged on Android, which may lead to inconsistent behavior that was previously patched out (for more context see #7310)
Old behavior:
iOS and Android:
double tap: child tap -> parent tap -> child double tap -> parent double tap
tap: child tap -> parent tap
New behavior (iOS):
double tap: child double tap
tap: child tap
New behavior (Android):
double tap: child double tap -> parent double tap
tap: child tap -> parent tap
There was a problem hiding this comment.
@edusperoni It is already inconsistent between the platforms and this PR was not intending to fix child/parent intercepting/cancelling/bubbling.
My understanding of the iOS implementation was that the UIGestureRecognizerDelegateImpl was for a single view as the NS view is passed in which can be seen here. It sounds like that is an incorrect understanding.
There was a problem hiding this comment.
Actually, the current implementation of events (and bubbling) seem to be consistent in both platforms (all events bubble and the same events trigger).
I'm aware this PR does not intend to fix child/parent bubbling, I'm pointing out that this is a behavior breaking change. The same delegate is used by all views, as seen here, so that line will affect child/parent bubbling and break consistency.
There was a problem hiding this comment.
Okay that is fair. I'm understanding now.
In your mind, where do we go from here? What would you like me to do?
Maybe @MartoYankov can weigh in on next steps?
There was a problem hiding this comment.
I don't believe this is a negative change, but I can think of 3 options:
- if we're detecting a tap gesture, bubble this information up to views on android and prevent tap recognition up the chain
NativeScript/tns-core-modules/ui/core/view/view.android.ts
Lines 397 to 399 in cf533a7
- Compare targets and required taps in
if (gestureRecognizer instanceof UITapGestureRecognizer && otherGestureRecognizer instanceof UITapGestureRecognizer) {, so events will keep bubbling - Document it as a breaking change
I believe 1 is out of scope of this PR and 2 may add unneeded complexity. Maybe the best option is really 3 until we reach a consensus on how gesture disambiguation should work in NS?
The impact of the change should be really low. The only plugin I know to handle multiple taps (nativescript-windowed-modal) only does it to prevent a parent tap when the child was tapped (using Hit Testing). My own plugin (nativescript-ng-ripple, soon to become one with nativescript-ripple) uses touch, so it probably won't be affected.
There was a problem hiding this comment.
We discussed this internally and we agree that 3 is probably the best option for now.
There was a problem hiding this comment.
@MCurran16 @edusperoni @MartoYankov Seems we have a problem with this specific change in UIGestureRecognizerDelegateImpl.gestureRecognizerShouldRecognizeSimultaneouslyWithGestureRecognizer(...) that breaks ActionBar usage scenario in all master/detail templates so I am reverting it for the time being -- see #7400.
|
test |
PR Checklist
What is the current behavior?
When you have a tap and double tap gesture recognizer on a view and you attempt to double tap, the tap handler fires. The tap gesture event should not fire if you're attempting a double tap.
What is the new behavior?
For both platforms, the
tapevent will not be fired when you're attempting adoubleTapgesture.Implements #7281
Additional Context
@MartoYankov
For android, I decided to not use
onSingleTapConfirmeddue to the delay that is described in this SO answer: https://stackoverflow.com/a/48844866 . I did try usingonSingleTapConfirmedand there was consistently a noticeable delay and sometimes it wasn't even fired.For iOS, the solution in the attached issue was implemented.
I also tried to get those files I changed to follow the NS code convention a bit more... hoping that's okay!
BREAKING CHANGES:
Old behavior:
New behavior:
Migration steps:
Move event handlers accordingly.