Cross handler interactions
Gesture handlers can "communicate" with each other to support complex gestures and control how they activate in certain scenarios.
There are two means of achieving that described in the sections below.
In each case, it is necessary to provide a reference of one handler as a property to the other.
Gesture handler relies on ref objects created using React.createRef()
and introduced in React 16.3.
Simultaneous recognition
By default, only one gesture handler is allowed to be in the ACTIVE
state.
So when a gesture handler recognizes a gesture it cancels all other handlers in the BEGAN
state and prevents any new handlers from receiving a stream of touch events as long as it remains ACTIVE
.
This behavior can be altered using the simultaneousHandlers
property (available for all types of handlers).
This property accepts a ref or an array of refs to other handlers.
Handlers connected in this way will be allowed to remain in the ACTIVE
state at the same time.
Use cases
Simultaneous recognition needs to be used when implementing a photo preview component that supports zooming (scaling) the photo, rotating and panning it while zoomed in.
In this case we would use a PinchGestureHandler
, RotationGestureHandler
and PanGestureHandler
that would have to simultaneously recognize gestures.
Example
See the "Scale, rotate & tilt" example from the GestureHandler Example App or view it directly on your phone by visiting our expo demo.
class PinchableBox extends React.Component {
// ...take a look on full implementation in an Example app
render() {
const imagePinch = React.createRef();
const imageRotation = React.createRef();
return (
<RotationGestureHandler
ref={imageRotation}
simultaneousHandlers={imagePinch}
onGestureEvent={this._onRotateGestureEvent}
onHandlerStateChange={this._onRotateHandlerStateChange}>
<Animated.View>
<PinchGestureHandler
ref={imagePinch}
simultaneousHandlers={imageRotation}
onGestureEvent={this._onPinchGestureEvent}
onHandlerStateChange={this._onPinchHandlerStateChange}>
<Animated.View style={styles.container} collapsable={false}>
<Animated.Image
style={[
styles.pinchableImage,
{
/* events-related transformations */
},
]}
/>
</Animated.View>
</PinchGestureHandler>
</Animated.View>
</RotationGestureHandler>
);
}
}
Awaiting other handlers
Use cases
A good example where awaiting is necessary is when we want to have single and double tap handlers registered for one view (a button). In such a case we need to make single tap handler await a double tap. Otherwise if we try to perform a double tap the single tap handler will fire just after we hit the button for the first time, consequently cancelling the double tap handler.
Example
See the "Multitap" example from GestureHandler Example App or view it directly on your phone by visiting our expo demo.
const doubleTap = React.createRef();
const PressBox = () => (
<TapGestureHandler
onHandlerStateChange={({ nativeEvent }) =>
nativeEvent.state === State.ACTIVE && Alert.alert('Single tap!')
}
waitFor={doubleTap}>
<TapGestureHandler
ref={doubleTap}
onHandlerStateChange={({ nativeEvent }) =>
nativeEvent.state === State.ACTIVE && Alert.alert("You're so fast")
}
numberOfTaps={2}>
<View style={styles.box} />
</TapGestureHandler>
</TapGestureHandler>
);