React-native: panResponder doesn't work with Modal

Created on 2 Jun 2017  路  19Comments  路  Source: facebook/react-native

Description

onMoveShouldSetPanResponder is not triggered inside the Modal component, when used outside is triggered just fine.

Reproduction Steps and Sample Code

https://snack.expo.io/HkttB70ZZ

  1. Click on the Touch me !! green box and the alert from the event should be triggered.
  2. Click on Click Open Modal to open the Modal.
  3. Click on the Touch me !! green box, observe that event is not triggered anymore.

Additional Information

  • React Native version: 0.44.2
  • Platform: iOS
  • Development Operating System: macOS
Locked

Most helpful comment

I tried @onlybenyang 's workaround and the modal now successfully releases its responder.
So Im using this for now:

render() {
    /**
     * Im using the TouchableWithoutFeedback with its View as a workaround
     * so that this component is swipable even when it is inside a modal,
     * because modals do not release their responder properly.
     */
    return (
      <Animated.View style={ { marginTop: this.position } } { ...this.panResponder.panHandlers }>
        <TouchableWithoutFeedback>
          <View>

            // The component's content goes here

          </View>
        </TouchableWithoutFeedback>
      </Animated.View>
    );
  }

All 19 comments

I tested in the last version v0.45.1 still doesn't work.

Same here!

Same here!
Additional Information

  • React Native version: 0.47.1
  • Platform: iOS
  • Development Operating System: macOS

Metoo..

I'm on react native : 0.41.2
Platform iOS & android.

same here, not working on .49

Any updates on this? It's still not working.

I try to wrap TouchableOpacity outside of the view, it works

I just had this issue,
I fixed it by following these instructions
https://github.com/facebook/react-native/issues/9786#issuecomment-262932857
Enjoy !

I tried @onlybenyang 's workaround and the modal now successfully releases its responder.
So Im using this for now:

render() {
    /**
     * Im using the TouchableWithoutFeedback with its View as a workaround
     * so that this component is swipable even when it is inside a modal,
     * because modals do not release their responder properly.
     */
    return (
      <Animated.View style={ { marginTop: this.position } } { ...this.panResponder.panHandlers }>
        <TouchableWithoutFeedback>
          <View>

            // The component's content goes here

          </View>
        </TouchableWithoutFeedback>
      </Animated.View>
    );
  }

Still trouble me.

The handlePanResponderMove function won't called when 2 fingers in the screen. But it will called when single finger touch and move.

  handlePanResponderMove = ({ nativeEvent }, gs) => {
    console.log('nativeEvent:', nativeEvent.changedTouches);
    // if (touches.length == 2) {
    //   let touch1 = touches[0];
    //   let touch2 = touches[1];
    //   console.log('touches:', touches);
    // }
    this.loop({ type: 'touchmove', gs });
  }

I put the responder under the Modal.

<Modal
  transparent
  animationType="fade"
  visible={this.state.modalVisible}
  onRequestClose={() => {}}
>
  <View style={{
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor: 'black',
  }} {...this._panResponder.panHandlers}>
    <Image style={{
      flex: 1,
      position: 'absolute',
      top,
      left,
      width: '100%',
      height: '100%',
      transform: [
        {scale},
      ]
    }}
    resizeMode={'contain'}
    source={source} />
  </View>
</Modal>

Info:

Environment:
  OS: macOS High Sierra 10.13.4
  Node: 9.5.0
  Yarn: 1.5.0
  npm: 5.7.1
  Watchman: 4.9.0
  Xcode: Xcode 9.3 Build version 9E145
  Android Studio: 3.1 AI-173.4720617

Packages: (wanted => installed)
  react: 16.0.0 => 16.0.0
  react-native: 0.50.1 => 0.50.1

@react-native-bot @tibbus Hope you can reopen this issue until facebook team fix it or tell any useful solution.

THANKS.

@FaiChou: I managed to get touches working by adding:

this._panResponder = PanResponder.create({
  ...
  onResponderTerminationRequest: () => false,
  ...
})

@onlybenyang @jakallergis What if I have more Touchables inside the wrapper TouchableWithoutFeedback? the inner Touchable does not respond to click event at all.

Why is this issue closed?
panResponder still does not work properly with the Modal component.
And none of the workarounds suggested here worked for me.

Check out react navigation's modal. Replaced a modal with its version of a modal, and registered touches perfectly: https://reactnavigation.org/docs/en/modal.html

For me what fixed the issue was making sure I included all of panresponder's methods. Personally all I was missing was...
onStartShouldSetPanResponder: (evt, gestureState) => true,
and once I added that it was fixed. If you can't get it to work try adding all of panresponder's methods just to check that you are not missing anything.

good luck!

@jrob-io your solution works for me, thanks!

This issue should not be closed. I just ran into it myself too. Should we just recreate it?

i get this bug too

For me I fixed this issue by following this steps

  • Firstly All your PanResponder functions must return true as following
this.panResponder = PanResponder.create({
    onMoveShouldSetPanResponder: () => true,
    onPanResponderMove: (evt, gestureState) => {
        console.warn('Start Moving');
        return true;
    },
});
  • Then you have to wrap your content with TouchableWithoutFeedback don't forgot to pass it any function as onPress prop because Touchables without onPress throwing exception on release
<View {...this.panResponder.panHandlers}>
    <TouchableWithoutFeedback onPress={() => {}}>
        {this.props.children}
    </TouchableWithoutFeedback>
</View>
Was this page helpful?
0 / 5 - 0 ratings