Improve gestures to allow for cancellation, interception and customizability #13
edusperoni
started this conversation in
1. Ideas & Discussions
Replies: 1 comment 1 reply
-
💯 agree this is something to work on. Ideally we should implement the UI Events spec with proper capture, target, bubble phases. Some testing would need to be done to measure the impact of implementing all the phases - but I would love to see it in NativeScript! In fact I started playing around with the idea earlier this year: https://play.nativescript.org/?template=play-vue&id=IzRhUq&v=1 |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I'll just copy paste my very old suggestion from the core repo:
NativeScript/NativeScript#7310
Is your feature request related to a problem? Please describe.
Currently, there is no way to cancel or intercept a gesture. Example: if you set a
tap
to a child and a parent, both will trigger. Custom gestures must also be handled manually withtouch
events.More often than not, when using
tap
, you just want onetap
to trigger. Say you have a card and an user picture inside the card. If you tap anywhere on the card you want to open a URL or show more details about the card, if you tap on the user picture, you want to show the user profile. Currently this completely breaks in {N} and requires workarounds, while works out of the box (and is the default behavior) in other frameworks. This makes developing complex UIs frustrating and actually recudes the usability ofTappableSpan
s #7076, since you can't reliably create atap
for a URL and another for the text, for example. If you check apps like Facebook and Instagram, this is used absolutely everywhere.Describe the solution you'd like
A Gesture Arena with
HitTestBehavior
andAllowMultipleGestureRecognizer
, similar to Flutter (https://medium.com/flutter-community/flutter-deep-dive-gestures-c16203b3434f), but allowing better bubbling (it seems flutter does not allow for two events of the same kind to be trigger simultaneously, like parent and childtap
).The current {N} implementation is like
AllowMultipleGestureRecognizer = true
andHitTestBehavior = translucent
, but with the added factor that no event is unique. Multiple gestures are recognized loosely and they all bubble to the parents.Ideally, we should be able to set additional properties to each event of a view (
tap
,drag
, etc), register our own gesture recognizers (like a raw gesture that returns true when recognized), and generate relations between them (custom gesture can't trigger along with child/parentswipe
, or childtap
has precedence over parenttap
or vice-versa, for example).Honestly, any implementation that allows the user to eat an event type would work better than the current bubbling.
Describe alternatives you've considered
Using booleans to detect child events and gesture detection and discard events when needed. This adds a lot of complexity in the UI code.
Additional context
I've already done some research on the possible implications and implementations. Maybe we could work on a proper API proposal.
iOS:
Currently, we're already running all recognizers simulaneously. This behavior can be expanded to add relations. Since we have
owner
references, we should be able to get these dynamically for the view (https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/coordinating_multiple_gesture_recognizers)https://github.com/NativeScript/NativeScript/blob/7d3f0d9e96976d257b17f9019ea0d101b827572f/tns-core-modules/ui/gestures/gestures.ios.ts#L18-L20
Using the same
owner
references, we could also do the same when deciding for exclusivity, or discarding similar events if that's what the view wants(https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/coordinating_multiple_gesture_recognizers/preferring_one_gesture_over_another)
Android:
Every
touchable
view on android returnstrue
ononTouchEvent
, so the event is always intercepted by the furthest child in the chain (http://codetheory.in/understanding-android-input-touch-events/). {N} solves this via an undocumented breaking change of NS 5.0 (mistakenly opened as #6606) in which allMotionEvent
s bubble up to their parents indiscriminately.https://github.com/NativeScript/NativeScript/blob/cf533a7b6d6607aefd39c06978578bb2b453eb3d/tns-core-modules/ui/core/view/view.android.ts#L397-L399
This behavior can be solved in Android by passing additional data up the chain, like what events were triggered by the
MotionEvent
.android.view.GestureDetector
triggers them synchronously, so we could store atriggered
variable that sets itself when an event has been triggered, which is later reset by theGesturesObserver
which is handling it.https://github.com/NativeScript/NativeScript/blob/05c2460fc4989dae4d7fa1ee52f6d54e0c3113f5/tns-core-modules/ui/gestures/gestures.android.ts#L333-L335
Possible edge case: parent wants to intercept event but child doesn't want bubbling.
Beta Was this translation helpful? Give feedback.
All reactions