useKeyboardHandler
useKeyboardHandler is a hook that offers low-level but more powerful API in comparison to useKeyboardAnimation. Using this hook you are getting an access to keyboard lifecycle events and you can easily determine the moment of the beginning animation, the end of the animation and get keyboard position in every frame of the animation.
Example
useKeyboardHandler(
{
onStart: (e) => {
"worklet";
},
onMove: (e) => {
"worklet";
},
onInteractive: (e) => {
"worklet";
},
onEnd: (e) => {
"worklet";
},
},
[],
);
Don't forget to add worklet directive to all onStart/onMove/onInteractive/onEnd handlers. Otherwise your code will throw exception.
These handlers are not workletized by default, since it's not a part of reanimated package.
Since onMove handler on iOS is based on CADisplayLink usage - you may need to add following content in Info.plist if you want to have your animations running at 120 FPS on devices with ProMotion displays:
+ <key>CADisableMinimumFrameDurationOnPhone</key>
+ <true/>
Event structure
height- height of the keyboard;progress- a value between0(closed) and1(opened) indicating relative keyboard position;duration- duration of the animation;target- tag of the focusedTextInput(or-1if the tag is not found).
Handlers
onStart
This function is called before the keyboard movement starts.
height and progress values will have
destination values, i. e. if keyboard was closed but will appear -
these values will have a values like "keyboard is already opened"
(progress will be equal to 1 and
height will have non-zero value).
useKeyboardHandler(
{
onStart: (e) => {
'worklet';
const willKeyboardAppear = e.progress === 1;
}
},
[]
);

useKeyboardHandler(
{
onStart: (e) => {
'worklet';
const willKeyboardAppear = e.progress === 1;
}
},
[]
);
onMove
This function will be called every frame when the keyboard changes its position.
useKeyboardHandler(
{
onMove: (e) => {
'worklet';
progress.value = e.progress;
height.value = e.height;
}
},
[]
);

useKeyboardHandler(
{
onMove: (e) => {
'worklet';
progress.value = e.progress;
height.value = e.height;
}
},
[]
);
onInteractive
This function will be called every frame when user changes position of the keyboard by the drag.
If finger is released and keyboard animates to its final destination, then
the standard onStart/onMove/onEnd
life cycles will be triggered.
useKeyboardHandler(
{
onInteractive: (e) => {
'worklet';
progress.value = e.progress;
height.value = e.height;
}
},
[]
);

useKeyboardHandler(
{
onInteractive: (e) => {
'worklet';
progress.value = e.progress;
height.value = e.height;
}
},
[]
);
This event is available only on Android >= 11. To receive it you need to use KeyboardGestureArea.
On iOS you need to specify keyboardDismissMode="interactive" on your ScrollView.
onEnd
This function will be called when the keyboard has completed its movement. The event will contain current keyboard metrics.
useKeyboardHandler(
{
onEnd: (e) => {
'worklet';
progress.value = e.progress;
height.value = e.height;
}
},
[]
);

useKeyboardHandler(
{
onEnd: (e) => {
'worklet';
progress.value = e.progress;
height.value = e.height;
}
},
[]
);