| id | gesture-composition |
|---|---|
| title | Gesture composition & interactions |
| sidebar_label | Gesture composition & interactions |
| sidebar_position | 5 |
import Competing from '!!raw-loader!.//_examples/hooks/Competing'; import Simultaneous from '!!raw-loader!.//_examples/hooks/Simultaneous'; import Exclusive from '!!raw-loader!.//_examples/hooks/Exclusive';
import RequireToFail from '!!raw-loader!.//_examples/props/RequireToFail'; import Block from '!!raw-loader!.//_examples/props/Block'; import SimultaneousWith from '!!raw-loader!.//_examples/props/SimultaneousWith';
RNGH3 simplifies gesture interaction through dedicated composition hooks and configuration properties. To choose the right approach, simply ask: Are all the gestures attached to the same component?
-
If yes: Use composition hooks. These allow you to bundle multiple gestures—including previously composed ones—into a single object for a GestureDetector.
-
If no: Use relation properties to manually define how gestures interact. Since these properties also support composed gestures, you can mix both methods for more complex layouts.
Only one of the provided gestures can become active at the same time. The first gesture to become active will cancel the rest of the gestures. It accepts variable number of arguments.
For example, lets say that you have a component that you want to make draggable but you also want to show additional options on long press. Presumably you would not want the component to move after the long press activates. You can accomplish this using useCompetingGestures:
<CollapsibleCode label="Show full example" expandedLabel="Hide full example" lineBounds={[9, 32]} src={Competing}/>
All of the provided gestures can activate at the same time. Activation of one will not cancel the other.
For example, if you want to make a gallery app, you might want user to be able to zoom, rotate and pan around photos. You can do it with useSimultaneousGestures:
Note: the
useSharedValueanduseAnimatedStyleare part ofreact-native-reanimated.
<CollapsibleCode label="Show full example" expandedLabel="Hide full example" lineBounds={[14, 81]} src={Simultaneous}/>
Only one of the provided gestures can become active. Priority is determined by the order of the aguments, where the first gesture has the highest priority, and the last has the lowest. A gesture can activate only after all higher-priority gestures before it have failed.
For example, if you want to make a component that responds to single tap as well as to a double tap, you can accomplish that using useExclusiveGestures:
<CollapsibleCode label="Show full example" expandedLabel="Hide full example" lineBounds={[8, 35]} src={Exclusive}/>
requireToFail allows to delay activation of the handler until all handlers passed as arguments to this method fail (or don't begin at all).
For example, you may want to have two nested components, both of them can be tapped by the user to trigger different actions: outer view requires one tap, but the inner one requires 2 taps. If you don't want the first tap on the inner view to activate the outer handler, you must make the outer gesture wait until the inner one fails:
<CollapsibleCode label="Show full example" expandedLabel="Hide full example" lineBounds={[8, 38]} src={RequireToFail}/>
block works similarly to requireToFail but the direction of the relation is reversed - instead of being one-to-many relation, it's many-to-one. It's especially useful for making lists where the ScrollView component needs to wait for every gesture underneath it. All that's required to do is to pass a ref, for example:
<CollapsibleCode label="Show full example" expandedLabel="Hide full example" lineBounds={[22, 86]} src={Block}/>
simultaneousWith allows gestures across different components to be recognized simultaneously. For example, you may want to have two nested views, both with tap gesture attached. Both of them require one tap, but tapping the inner one should also activate the gesture attached to the outer view:
<CollapsibleCode label="Show full example" expandedLabel="Hide full example" lineBounds={[8, 37]} src={SimultaneousWith}/>