Imagine simple ScrollView with multiple TextInputs like
  <ScrollView style={styles.container}>
    <TextInput style={styles.input} />
    <TextInput style={styles.input} />
  </ScrollView>
When I enter first input, keyboard opens and I can type text. When I want to change to second input I need to twice tap - first type closes keyboard and only second tap opens the keyboard for second input.
One solution is to use keyboardShouldPersistTaps={true} - switching works fine however then keyboard is not closed at all and the keyboard can cover some of the later inputs (or buttons).
I can also use keyboardDismissMode however that just close keyboard on drag.
My question is how to combine those two behaviour - into IMHO the best user experience - when I click another input, the focus is changed immediately without reopening keyboard and when I tap somewhere else the keyboard is closed?
I am using RN0.22 and sample application is available at https://rnplay.org/apps/kagpGw
UPDATE - This problem might have been solved in RN 0.40 - see https://github.com/facebook/react-native/commit/552c60192172f6ec503181c060c08bbc5cbcc5a4
I solved my problem with this code
<ScrollView
   keyboardDismissMode='on-drag'
   keyboardShouldPersistTaps={true}
>
                        In the new react-native versions you can persist the on scrollview click event like below:
<ScrollView
      keyboardShouldPersistTaps='always'
      keyboardDismissMode={'interactive'}></ScrollView>
The main trick is keyboardShouldPersistTaps='always'
This SO answer isn't exactly what you're asking for, but will auto-slide the window out from behind the keyboard when a TextInput has focus; resolving your keyboard can cover some of the later inputs (or buttons) issue.
At the end I found solution that is not optimal (from coding perspective) but works from user perspective. I made small component that can be used instead of ScrollView:
export class InputScrollView extends React.Component {
  constructor(props, ctx) {
      super(props, ctx);
      this.handleCapture = this.handleCapture.bind(this);
  }
  render() {
    return (
      <ScrollView keyboardShouldPersistTaps={true} keyboardDismissMode='on-drag'>
        <View onStartShouldSetResponderCapture={this.handleCapture}>
          {this.props.children}
        </View>
      </ScrollView>
    );
  }
  handleCapture(e) {
    const focusField = TextInputState.currentlyFocusedField();
    const target = e.nativeEvent.target;
    if (focusField != null && target != focusField){
      const inputs = this.props.inputs;
      if (inputs && inputs.indexOf(target) === -1) {
        dismissKeyboard();
      }
    }
  }
}
InputScrollView.propTypes = {
  inputs : React.PropTypes.array,
}
The only drawback is that I need to collect node handles (as returned by React.findNodeHandle) of all text inputs "manually" and pass it to the component as an array.
By looking at https://facebook.github.io/react-native/docs/scrollview.html#keyboarddismissmode I find out a method that can do these:
The code is as follows:
<ScrollView
  keyboardDismissMode="none"
  keyboardShouldPersistTaps="handled"
>
  {content}
</ScrollView>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With