Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PanResponder over a TextInput in react-native

Tags:

react-native

I am facing an issue on React-native. I have TextInput that takes the whole screen. I would like to change the content of this text input when the user swipes up or down. For this I am using a PanResponder.

The problem is that the PanResponder steals the focus from the TextInput: when I click on the TextInput, the keyboard doesn't appear and I can't change its value.

Is there a way to have both the PanResponder and the Textinput coexist, so that a tap will focus on the TextInput and a swipe will still trigger the PanResponder callbacks?

I reduced the code to the minimum needed to reproduce the issue:

export default class EditNoteScreen extends Component {
  componentWillMount() {
    this.panResponder = PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onStartShouldSetPanResponderCapture: () => true,
      onMoveShouldSetResponderCapture: () => true,
      onMoveShouldSetPanResponderCapture: () => true
    });
  }

  render() {
    return (
      <View style={stylesNote.editScreen} {...this.panResponder.panHandlers}>
        <View style={stylesNote.editScreenContent}>
          <TextInput style={stylesNote.editScreenInput}>
            Hello
          </TextInput>
        </View>
      </View>
    );
  }
}

Styles:

  editScreen: {
    flex: 1
  },

  editScreenContent: {
    flex: 5
  },

  editScreenInput: {
    flex: 1,
    borderColor: "transparent",
    paddingLeft: 20,
    paddingRight: 10
  }
like image 203
Ryan Pergent Avatar asked Jun 02 '17 22:06

Ryan Pergent


1 Answers

Yeah it is possible that PanResponder and the TextInput to coexist. Your problem is that you are always returning true from your panhandlers. Which means that panhandlers gets the focus.

For example one of my projects I wanted PanResponder only capture event when moving the finger. But I also had TouchableOpacity inside too so PanResponder always stole the focus.

To resolve this I modified onMoveShouldSetPanResponderCapture function with custom logic and not to always return true. So in your case I do not know what you are doing but all panhandlers get nativeEvent and gestureState as parameters. So you can for example use them in your custom logic.

Here is an example:

onMoveShouldSetPanResponderCapture: (evt, gestureState) => Math.abs(gestureState.dy) > 5

This means that if the y-axis movement is over 5 pixels only then panresponder will get the focus. Otherwise other elements for example your TextInput will get focus.

like image 61
Henrik R Avatar answered Sep 23 '22 18:09

Henrik R