What are Keyboard Change Frame Events in React Native
Posted By: Harish

In keyboard listener events, we have keyboardWillShow and keyboardWillHide events which are triggered before the change. Similarly, we have keyboardDidShow and keyboardDidHide events which are triggered after the completion of change.
Addition to those events, we have another two events, keyboardWillChangeFrame
and keyboardDidChangeFrame
to get the info about the keyboard.
In general terms, these two change frame events are nothing but the mix of keyboardWillShow
, keyboardDidShow
, keyboardWillHide
and keyboardDidHide
events.
Showing or hiding a keyboard is nothing but changes in keyboard frame size and its position. These change frame events are useful to get the properties of the keyboard when used in different scenarios like Split View, Slide Over, and Stage Manager.
Please note that these change frame events are only available for iOS and iPadOS operating systems, not for android operating systems. You can know more about the compatibility from react native documentation.
You can know more about keyboard will change frame and did change frame events from iOS documentation.
Lets see a simple implementation of change frame with logs.
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
We need to import a TextInput
component and Keyboard
module to get started.
//app.tsx
import {
TextInput,
...
} from "react-native";
...
<TextInput
style={styles.input}
keyboardType='default'
returnKeyType='search'
placeholder="Search"
placeholderTextColor='gray'
autoFocus={true}
showSoftInputOnFocus={true}
/>
...
We have to call Keyboard.addListener()
with keyboardWillChangeFrame
and keyboardDidChangeFrame
events and their callback functions.
//app.tsx
...
useEffect(() => {
const willChangeSub = Keyboard.addListener('keyboardWillChangeFrame', willChange);
const didChangeSub = Keyboard.addListener('keyboardDidChangeFrame', didChange);
return () => {
willChangeSub.remove();
didChangeSub.remove();
};
}, []);
const willChange = (e: KeyboardEvent) => {
console.log("Will Change: ", e);
};
const didChange = (e: KeyboardEvent) => {
console.log("Did Change: ", e);
};
...
If we run the app, we will see that the events will get triggered when the keyboard is opened, screen rotated or hidden.
This is nothing but changes in keyboard, we can also see frame changes when we open emoji keyboard too.
#logs
LOG Will Change: {"duration": 350, "easing": "keyboard", "endCoordinates": {"height": 260, "screenX": 0, "screenY": 407, "width": 375}, "isEventFromThisApp": true, "startCoordinates": {"height": 216, "screenX": 0, "screenY": 667, "width": 375}}
LOG Did Change: {"duration": 350, "easing": "keyboard", "endCoordinates": {"height": 260, "screenX": 0, "screenY": 407, "width": 375}, "isEventFromThisApp": true, "startCoordinates": {"height": 216, "screenX": 0, "screenY": 667, "width": 375}}
Complete code,
//app.tsx
import { useEffect } from "react";
import {
View,
Text,
StyleSheet,
TextInput,
Keyboard,
KeyboardEvent
} from "react-native";
export const App = () => {
useEffect(() => {
const willChangeSub = Keyboard.addListener('keyboardWillChangeFrame', willChange);
const didChangeSub = Keyboard.addListener('keyboardDidChangeFrame', didChange);
return () => {
willChangeSub.remove();
didChangeSub.remove();
};
}, []);
const willChange = (e: KeyboardEvent) => {
console.log("Will Change: ", e);
};
const didChange = (e: KeyboardEvent) => {
console.log("Did Change: ", e);
};
return (
<View style={styles.container}>
<Text style={styles.text}>
ifelsething.com
</Text>
<Text style={styles.text}>
Events when keyboard frames change
</Text>
<TextInput
style={styles.input}
keyboardType='default'
returnKeyType='search'
placeholder="Search"
placeholderTextColor='gray'
autoFocus={true}
showSoftInputOnFocus={true}
/>
</View>
);
}
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'
},
});