React-native dismiss Keyboard when focus out / clicked somewhere else, outside textfield

34.4k views Asked by At

I'm new to react-native. I have a textfield(Input). I want to the Keyboard to be dismissed when user clicks somewhere else except input field. I tried several solutions suggested here like TouchableWithoudFeedback, but they did not work. Also, the point which is not clear to me, I can use any function inside onFocus, on the other hand, nothing worked in onBlur or onEndEditing Here is my code of Input component.

<InputGroup borderType='rounded' style={styles.inputGrp}>
                                    <Input placeholder={'Password'} secureTextEntry={true} style={styles.input}
                                           onChangeText={(pin1) => this.setState({pin1: pin1})}
                                           value={this.state.pin1}
                                           maxLength={8}
                                    />
4

There are 4 answers

4
Irfan Ayaz On

You can use keyboard's done button to dismiss the keyboard when the user is done entering text.

                                <TextInput placeholder={'Password'} secureTextEntry={true} style={styles.input}
                                       onChangeText={(pin1) => this.setState({pin1: pin1})}
                                       value={this.state.pin1}
                                       maxLength={8}
                                       onSubmitEditing={ ()=> this.dismissKeyboardAction()}/>

Define this method somewhere.

dismissKeyboardAction() {
    dismissKeyboard();
  }

Don't forget to import

var dismissKeyboard = require('dismissKeyboard');

Also, there are several workarounds possible if you want to dismiss keyboard when the user taps anywhere else other than keyboard whenever the keyboard is visible. Use keyboardWillShow and keyboardWillHide methods to set and unset a state variable something like isKeyboardVisible = true. Also, based on this state variable, if true, render an overlay over your entire screen (transparent TouchableHighlight or TouchableWithoutFeedback) with absolute coordinates (from height 0 to screen height - keyboardheight) and call the same dismisskeyboard() method on tap.

Something like

  componentWillMount() {
  if (Platform.OS === 'ios') {
      Keyboard.addListener('keyboardWillShow', this.keyboardWillShow); //not supported on Android
      Keyboard.addListener('keyboardWillHide', this.keyboardWillHide); //not supported on Android
    }
    else {
      Keyboard.addListener('keyboardDidShow', this.keyboardWillShowAndroid);
      Keyboard.addListener('keyboardDidHide', this.keyboardWillHideAndroid);
   }
}
keyboardWillShow (e) {
    let newSize = e.endCoordinates.height
    this.setState({
      keyboardHeight: newSize,
      isKeyboardVisible: true
    })
  }
keyboardWillHide (e) {
    this.setState({
      keyboardHeight: 0,
      isKeyboardVisible: false
    })
  }

You can get screen height like this

import Dimensions from 'Dimensions';
var height = Dimensions.get('window').height;
    var width = Dimensions.get('window').width;

From here, you can render a transparent touchable component over your UI only when the keyboard is visible and dismiss keyboard in the onPress method.

3
Noitidart On

Solution here is to wrap your form's with <ScrollView keyboardShouldPersistTaps="handled" />. The keyboardShouldPersistTaps is the important part. It can also be "never" for keyboardShouldPersistTaps, but then keyboard might dismiss too easily. This solution was shared at https://stackoverflow.com/a/41429871/1828637

0
Aakshaye On

For someone like me who wants to use it with a FlatList, you have to use the keyboardShouldPersistTaps prop as follows:

<FlatList
   data
   ...otherProps
   keyboardShouldPersistTaps="always"
/>
2
Abdul Azeem On

here is the solution to that above question: Hide keyboard in react native

import {Keyboard, TouchableWithoutFeedback} from 'react-native'

wrap your root component with TouchableWithoutFeedback and trigger Keyboard.dismiss at onPress, like following

<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
    <View style={{flex: 1}}>
          ........
          //rest of the component
          ........
    </View>
</TouchableWithoutFeedback>