ifelsething logoifelsething

Get Event Before Keyboard Opening or Closing in React Native

Posted By: Harish
Get Event Before Keyboard Opening or Closing in React Native

Sometimes we need to know the keyboard event before opening or closing so that we can perform some actions. Like in our hiding floating button example to dismiss the keyboard and to animate our view accordingly.

Create A New Project

Create a new react-native project by using npx. Check documentation for creating a new react native project.

npx react-native@latest init KeyboardRN

Import Keyboard Module

For our example, we need to import a TextInput and Keyboard module.

To get events beforehand, we need to call Keyboard.addListener() with an event name and a callback. Here, we need events before the action, so we need to use keyboardWillShow and keyboardWillHide events.

These events are called when the keyboard starts opening or closing. If you want events after opening or closing the keyboard, you can use use keyboardDidShow and keyboardDidHide events.

Please note that only keyboardDidShow and keyboardDidHide events work in android devices, other events will not work.

So, keyboardWillShow and keyboardWillHide are only for react native iOS apps.

Import useEffect from react and call listener method inside useeffect. Pass the name of the event and callbacks.

//app.tsx

...

useEffect(() => {
  const showSub = Keyboard.addListener('keyboardWillShow', showKeyboard);
  const hideSub = Keyboard.addListener('keyboardWillHide', hideKeyboard);
  return () => {
    showSub.remove();
    hideSub.remove();
  };
}, []);
const showKeyboard = (e: KeyboardEvent) => {
  console.log("Start Show: ", e);
};
const hideKeyboard = (e: KeyboardEvent) => {
  console.log("Start Hide: ", e);
};

...

We are starting a subscription inside useEffect hook to get events to their callbacks. If we run the app, open and close the keyboard, you can see logs in their respective callback functions.

#logs
 Start Show:  {"duration": 250, "easing": "keyboard", "endCoordinates": {"height": 260, "screenX": 0, "screenY": 407, "width": 375}, "isEventFromThisApp": true, "startCoordinates": {"height": 44, "screenX": 0, "screenY": 667, "width": 375}}
 Start Hide:  {"duration": 250, "easing": "keyboard", "endCoordinates": {"height": 44, "screenX": 0, "screenY": 667, "width": 375}, "isEventFromThisApp": true, "startCoordinates": {"height": 260, "screenX": 0, "screenY": 407, "width": 375}}

Complete code,

//app.tsx
import { useEffect } from "react";
import {
  View,
  Text,
  StyleSheet,
  TextInput,
  Keyboard,
  KeyboardAvoidingView,
  Platform,
  SafeAreaView,
  StatusBar,
  KeyboardEvent
} from "react-native";

export const App = () => {
  useEffect(() => {
    const showSub = Keyboard.addListener('keyboardWillShow', showKeyboard);
    const hideSub = Keyboard.addListener('keyboardWillHide', hideKeyboard);
    return () => {
      showSub.remove();
      hideSub.remove();
    };
  }, []);
  const showKeyboard = (e: KeyboardEvent) => {
    console.log("Start Show: ", e);
  };
  const hideKeyboard = (e: KeyboardEvent) => {
    console.log("Start Hide: ", e);
  };
  return (
    <KeyboardAvoidingView
      style={{ flex: 1 }}
      behavior={
        Platform.OS === 'ios'
          ? 'padding'
          : 'height'
      }
    >
      <SafeAreaView style={{ flex: 1 }}>
        <StatusBar
          barStyle="dark-content"
        />
        <View style={styles.container}>
          <Text style={styles.text}>
            ifelsething.com
          </Text>
          <Text style={styles.text}>
            Event before showing or closing keyboard
          </Text>
          <TextInput
            style={styles.input}
            keyboardType='default'
            returnKeyType='search'
            placeholder="Search"
            placeholderTextColor='gray'
            autoFocus={true}
            showSoftInputOnFocus={true}
          />
        </View>
      </SafeAreaView>
    </KeyboardAvoidingView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    margin: 10,
    gap: 20,
  },
  input: {
    borderColor: 'blue',
    borderWidth: 1,
    borderRadius: 10,
    padding: 10,
    fontSize: 15,
    color: 'black',
  },
  text: {
    fontSize: 15,
    color: 'black',
    fontStyle: 'italic'
  },
});

Share is Caring

Related Posts