Last active
January 25, 2025 15:56
-
-
Save nemorize/058f85ada6beb5f214ffdddf913b370b to your computer and use it in GitHub Desktop.
[RN] Get a proper animated keyboard height even if the user starts back gesture in iOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { clamp, interpolate, useAnimatedKeyboard, useAnimatedReaction, useSharedValue } from 'react-native-reanimated' | |
import { useSafeAreaInsets } from 'react-native-safe-area-context' | |
/** | |
* useAnimatedKeyboard() returns 0 height when back gesture has been started. | |
* This function handles not to return 0 even user starts the back gesture. | |
* | |
* @param {number} safeAreaPad Add a bottom safe area padding value, depends on keyboard state. | |
*/ | |
export function useKeyboardHeight (safeAreaPad: number | undefined = 8) { | |
const insets = useSafeAreaInsets() | |
const raKeyboard = useAnimatedKeyboard() | |
const firstStoredRaKeyboardValue = useSharedValue(0) | |
const secondStoredRaKeyboardValue = useSharedValue(0) | |
/** | |
* 1. Store previous animated keyboard height. | |
*/ | |
useAnimatedReaction(() => raKeyboard.height.value, () => { | |
secondStoredRaKeyboardValue.value = firstStoredRaKeyboardValue.value | |
firstStoredRaKeyboardValue.value = raKeyboard.height.value | |
}) | |
/** | |
* 2. If the keyboard height has been SUDDENLY shrunk, use the value from step 1. | |
* 3. If not, use the regular animated keyboard height. | |
*/ | |
const keyboardValue = useSharedValue(0) | |
useAnimatedReaction(() => raKeyboard.height.value, () => { | |
if (raKeyboard.height.value === 0 && secondStoredRaKeyboardValue.value > 50) { | |
keyboardValue.value = secondStoredRaKeyboardValue.value + (safeAreaPad ?? 0) | |
} else { | |
keyboardValue.value = raKeyboard.height.value + (safeAreaPad !== undefined ? interpolate( | |
clamp(raKeyboard.height.value, 0, 50), | |
[ 0, 50 ], | |
[ insets.bottom, safeAreaPad ], | |
) : 0) | |
} | |
}) | |
return keyboardValue | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment