Keyboard Handling in React Native

How to make your app respond gracefully on keyboard appearance? So far I have tried keyboard-aware-scroll, keyboardspacer and keyboard Avoiding view

Keyboard avoiding view didn't help at all I have tried it several times but it doesn't even respond to keyboard appearance.

Keyboardspacer gracefully works but in many cases it destroys the whole UI by crushing other view

keyboardaware scroll works when there is no scroll in the app but for long forms it doesn't work.

android:windowSoftInputMode="adjustPan" only works for android

What are the other options that we have for the app to gracefully respond when keyboard appears.

What do you use in your apps?

4 answers

  • answered 2018-11-08 07:16 Rajneesh Shukla

    You can find following usefull answer related your question.

    Q.How to change the Softkeyboard “Enter” button Text in android? https://stackoverflow.com/a/53098939/6477946

    Q. How to close or hide SoftKeyBoard

    https://stackoverflow.com/a/53077131/6477946

  • answered 2018-11-08 07:51 Georgiy T.

    For my projects I use react-native-keyboard-aware-scroll-view as well as KeyboardAvoidingView (try to play with behavior prop, it depends on your styling).

    Take a look in Android configuration section in docs of react-native-keyboard-aware-scroll-view. I think it's something that you're looking for.

  • answered 2018-11-08 14:05 Danilo

    If none of these libraries does what you need, you can adjust your view manually by using the Keyboard module (docs at https://facebook.github.io/react-native/docs/keyboard) With it you can react when you know a keyboard opens or closes, like so:

    import * as React from 'react';
    import { Keyboard } from 'react-native';
    
    class MyComponent extends React.Component {
      componentDidMount() {
          this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this.keyboardDidHide);
          this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this.keyboardDidShow);
      }
    
      componentWillUnmount() {
        this.keyboardDidHideListener.remove();
        this.keyboardDidShowListener.remove();
      }
    
      keyboardDidShow = () => {
          //Fix your view for when a keyboard shows
      };
    
      keyboardDidHide = () => {
          //Fix your view for when a keyboard hides
      };
    
        //Rest of component...
    
    }
    

  • answered 2018-11-09 05:44 Rajneesh Shukla

    The problem with keyboard not dismissing gets more severe if you have keyboardType='numeric', as there is no way to dismiss it.

    Replacing View with ScrollView is not a correct solution, as if you have multiple textInputs or buttons, tapping on them while the keyboard is up will only dismiss the keyboard.

    Correct way is to encapsulate View with TouchableWithoutFeedback and calling Keyboard.dismiss()

    EDIT: You can now use ScrollView with keyboardShouldPersistTaps='handled' to only dismiss the keyboard when the tap is not handled by the children (ie. tapping on other textInputs or buttons)

    If you have

    <View style={{flex: 1}}>
        <TextInput keyboardType='numeric'/>
    </View>
    

    Change it to

    <ScrollView contentContainerStyle={{flexGrow: 1}}
      keyboardShouldPersistTaps='handled'
    >
      <TextInput keyboardType='numeric'/>
    </ScrollView>
    or
    
    import {Keyboard} from 'react-native'
    
    <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
        <View style={{flex: 1}}>
            <TextInput keyboardType='numeric'/>
        </View>
    </TouchableWithoutFeedback>
    EDIT: You can also create a Higher Order Component to dismiss the keyboard.
    
    import React from 'react';
    import { TouchableWithoutFeedback, Keyboard, View } from 'react-native';
    
    const DismissKeyboardHOC = (Comp) => {
      return ({ children, ...props }) => (
        <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
          <Comp {...props}>
            {children}
          </Comp>
        </TouchableWithoutFeedback>
      );
    };
    

    const DismissKeyboardView = DismissKeyboardHOC(View) Simply use it like this

    ...

    render() {
        <DismissKeyboardView>
            <TextInput keyboardType='numeric'/>
        </DismissKeyboardView>
    }
    

    NOTE: the accessible={false} is required to make the input form continue to be accessible through VoiceOver. Visually impaired people will thank you!