React Native Zoomable View - child component should have onPress and be pannable

719 Views Asked by At

I have a parent component (ReactNativeZoomableView) in it there a nested component with clickable elements, the issue is that I want user to be able to press on the element to open it's sidemenu or press and pan to move around the screen.

library used https://www.npmjs.com/package/@openspacelabs/react-native-zoomable-view?activeTab=readme#pan-responder-hooks

Panning outside Element works fine, just on the element it doesnt.

<ReactNativeZoomableView
  ref={zoomRef}
  maxZoom={1.5}
  minZoom={0.5}
  initialZoom={1}
>
<Svg 
  width={width} 
  height={height}
  style={{backgroundColor:'red'}}
>
 {nodeElements.map((element, element) => {
   <Element
     element={element}
     element={element}
    />
 }}
</Svg>
</ReactNativeZoomableView>

The Element looks like the following:

<G
 onPress={handlePress}
>
.....
</G>

I have tried using onMoveShouldSetResponderCapture to have the pan event handled by the parent, that didnt work. Tried having pandhandlers also didnt work.

Sorry if the post is in bad structure, will provide any needed code or info. Thanks in advance

1

There are 1 best solutions below

1
Richy On

Go to the File in the Package: ReactNativeZoomableView.tsx There you have to add the onStartShouldSetPanResponderCapture. Fot me this solved the Issue.

constructor(props) {
super(props);

this.gestureHandlers = PanResponder.create({
  onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,
  onPanResponderGrant: this._handlePanResponderGrant,
  onPanResponderMove: this._handlePanResponderMove,
  onPanResponderRelease: this._handlePanResponderEnd,
  onPanResponderTerminate: (evt, gestureState) => {
    // We should also call _handlePanResponderEnd
    // to properly perform cleanups when the gesture is terminated
    // (aka gesture handling responsibility is taken over by another component).
    // This also fixes a weird issue where
    // on real device, sometimes onPanResponderRelease is not called when you lift 2 fingers up,
    // but onPanResponderTerminate is called instead for no apparent reason.
    this._handlePanResponderEnd(evt, gestureState);
    this.props.onPanResponderTerminate?.(
      evt,
      gestureState,
      this._getZoomableViewEventObject()
    );
  },
  onPanResponderTerminationRequest: (evt, gestureState) =>
    !!this.props.onPanResponderTerminationRequest?.(
      evt,
      gestureState,
      this._getZoomableViewEventObject()
    ),
  // Defaults to true to prevent parent components, such as React Navigation's tab view, from taking over as responder.
  onShouldBlockNativeResponder: (evt, gestureState) =>
    this.props.onShouldBlockNativeResponder?.(
      evt,
      gestureState,
      this._getZoomableViewEventObject()
    ) ?? true,
  onMoveShouldSetPanResponderCapture: (evt, gestureState) => Math.abs(gestureState.dx)>3 || Math.abs(gestureState.dy)>3,
  });

Interesting Part is in the last few Lines.