Describe the bug
On iOS, useReanimatedKeyboardAnimation() can intermittently remain at height.value === 0 while the system keyboard is visibly open. We observed this after both normal keyboard presentation and app foregrounding.
The system keyboard state is still available at the same moment: Keyboard.metrics()?.height reports 308–335 points. This leaves views driven by the controller at their keyboard-closed position.
Sanitized production observations:
- 4 self-healed occurrences across 2 users
- iOS 26.2.1 and 26.5.2
- system height: 308–335
- controller height: 0
- 3 checks triggered by
keyboardDidShow
- 1 check triggered when the app returned to the foreground with visible keyboard metrics
This appears related to #864, but the stale direction here is the reverse: the keyboard is visible while the controller reports closed.
Code snippet
The provider is mounted at the application root:
<KeyboardProvider preload>{children}</KeyboardProvider>
Our current application-level recovery waits two animation frames, then compares the controller and React Native system measurements:
const systemHeight = Keyboard.metrics()?.height ?? 0;
const controllerHeight = height.value;
if (systemHeight > 1 && Math.abs(controllerHeight) <= 1) {
recoveryHeight.value = systemHeight;
recoveryActive.value = true;
}
We run that reconciliation after keyboardDidShow, keyboardDidChangeFrame, mount, and transition to an active app state. It restores the layout successfully, but the controller's shared value itself remains stale until a later keyboard cycle.
Repo for reproducing
We do not have a deterministic reproduction repository. The issue is intermittent in production. We can provide more sanitized measurements or test a diagnostic build if that would help.
On an iOS 26.5 simulator, normal cold focus and hide/reopen cycles update the controller correctly. The simulator hides the software keyboard when the app is backgrounded, so it does not reproduce the production restoration path where the keyboard remains visible.
To Reproduce
Observed sequence:
- Focus a text input using a root
KeyboardProvider with preload.
- Leave the keyboard visible.
- Background and later foreground the app.
- Intermittently, observe a visible keyboard and
Keyboard.metrics()?.height > 0, while useReanimatedKeyboardAnimation().height.value === 0.
The same stale state has also occurred immediately after keyboardDidShow, so preloading or foreground restoration alone does not explain every occurrence.
Expected behavior
When the app becomes active with an already-visible keyboard, the provider should reconcile its shared height/progress values with the current keyboard frame. A current-frame query or documented reconciliation API would also let consumers restore the provider state without maintaining a parallel layout path.
Screenshots
We cannot share production screenshots, but the sanitized measurements above were captured at the same point where our fallback moved the composer above the keyboard.
Smartphone (please complete the following information):
- Desktop OS: macOS
- Device: production iPhones; dedicated simulator verification used an iOS 26.5 iPhone simulator
- OS: iOS 26.2.1 and 26.5.2
- RN version: 0.83.6
- RN architecture: Fabric
- JS engine: Hermes
- Library version: 1.21.13
- Expo version: 55.0.26
- Reanimated version: 4.3.1
Additional context
I inspected the iOS state path in 1.22.2 before reporting this. The shared values still appear to be updated from keyboard callbacks, and I did not find a foreground/current-frame reconciliation path, so upgrading alone does not appear to address this case.
Related reports:
Describe the bug
On iOS,
useReanimatedKeyboardAnimation()can intermittently remain atheight.value === 0while the system keyboard is visibly open. We observed this after both normal keyboard presentation and app foregrounding.The system keyboard state is still available at the same moment:
Keyboard.metrics()?.heightreports 308–335 points. This leaves views driven by the controller at their keyboard-closed position.Sanitized production observations:
keyboardDidShowThis appears related to #864, but the stale direction here is the reverse: the keyboard is visible while the controller reports closed.
Code snippet
The provider is mounted at the application root:
Our current application-level recovery waits two animation frames, then compares the controller and React Native system measurements:
We run that reconciliation after
keyboardDidShow,keyboardDidChangeFrame, mount, and transition to an active app state. It restores the layout successfully, but the controller's shared value itself remains stale until a later keyboard cycle.Repo for reproducing
We do not have a deterministic reproduction repository. The issue is intermittent in production. We can provide more sanitized measurements or test a diagnostic build if that would help.
On an iOS 26.5 simulator, normal cold focus and hide/reopen cycles update the controller correctly. The simulator hides the software keyboard when the app is backgrounded, so it does not reproduce the production restoration path where the keyboard remains visible.
To Reproduce
Observed sequence:
KeyboardProviderwithpreload.Keyboard.metrics()?.height > 0, whileuseReanimatedKeyboardAnimation().height.value === 0.The same stale state has also occurred immediately after
keyboardDidShow, so preloading or foreground restoration alone does not explain every occurrence.Expected behavior
When the app becomes active with an already-visible keyboard, the provider should reconcile its shared height/progress values with the current keyboard frame. A current-frame query or documented reconciliation API would also let consumers restore the provider state without maintaining a parallel layout path.
Screenshots
We cannot share production screenshots, but the sanitized measurements above were captured at the same point where our fallback moved the composer above the keyboard.
Smartphone (please complete the following information):
Additional context
I inspected the iOS state path in 1.22.2 before reporting this. The shared values still appear to be updated from keyboard callbacks, and I did not find a foreground/current-frame reconciliation path, so upgrading alone does not appear to address this case.
Related reports:
useReanimatedKeyboardAnimation()state