Since upgrading to React Native 0.76 (via Expo 52) I've been trying to track down an issue with KeyboardAvoidingView on iPadOS. Despite the resolution of a related bug in React Native, the issue persisted in a project using react-native-reanimated and the New Architecture.
After rotation, the KeyboardAvoidingView eventually stops updating properly. The root cause is that the onLayouthandler stops being called. This causes _relativeKeyboardHeight to calculate the wrong height due to a stale frame height. As such, the height is set to 0 and no padding is applied.
The onLayout bug is not limited to KeyboardAvoidingView. It seems that any React Native project using react-native-reanimated will eventually stop firing onLayout after rotation on iPadOS. This issue is limited to the New Architecture. If I switch to the old architecture, the issue does not reproduce.
The provided repro shows this behavior. When running in a simulator or device, rotating the screen will show the keyboard either pushing up the main content with too much padding (simulator) or hiding the input text box completely (real device). The console.log also shows an extra onLayout being called when an Animated.View is present in the DOM, right before onLayout stops firing. Removing the Animated.View prevents this issue from occurring, and there is only a single onLayout call during rotation.
I thought this issue may have been Expo specific. However, after further testing and isolation of the reproducer, I found that it can be reproduced using React Native without Expo as well. I also isolated the issue to react-native-reanimated, initially believing it was due to an interaction with react-native-gesture-handler.
Steps to reproduce
Launch the reproducer on an iPad simulator with npm run ios
Focus the text input at the bottom
Open the on screen keyboard
Rotate screen
Note that onLayout has been printed twice in the log
Rotate the screen again
Note that the KeyboardAvoidingView has applied incorrect padding and that onLayout was not printed in the log
Description
Since upgrading to React Native 0.76 (via Expo 52) I've been trying to track down an issue with
KeyboardAvoidingView
on iPadOS. Despite the resolution of a related bug in React Native, the issue persisted in a project usingreact-native-reanimated
and the New Architecture.After rotation, the
KeyboardAvoidingView
eventually stops updating properly. The root cause is that theonLayout
handler stops being called. This causes_relativeKeyboardHeight
to calculate the wrong height due to a stale frame height. As such, the height is set to 0 and no padding is applied.The
onLayout
bug is not limited toKeyboardAvoidingView
. It seems that any React Native project using react-native-reanimated will eventually stop firingonLayout
after rotation on iPadOS. This issue is limited to the New Architecture. If I switch to the old architecture, the issue does not reproduce.The provided repro shows this behavior. When running in a simulator or device, rotating the screen will show the keyboard either pushing up the main content with too much padding (simulator) or hiding the input text box completely (real device). The
console.log
also shows an extraonLayout
being called when anAnimated.View
is present in the DOM, right beforeonLayout
stops firing. Removing theAnimated.View
prevents this issue from occurring, and there is only a singleonLayout
call during rotation.I thought this issue may have been Expo specific. However, after further testing and isolation of the reproducer, I found that it can be reproduced using React Native without Expo as well. I also isolated the issue to react-native-reanimated, initially believing it was due to an interaction with react-native-gesture-handler.
Steps to reproduce
npm run ios
onLayout
has been printed twice in the logKeyboardAvoidingView
has applied incorrect padding and thatonLayout
was not printed in the logSnack or a link to a repository
https://github.com/mhoran/keyboard-avoiding-view-repro/
Reanimated version
3.16.1
React Native version
0.76.1
Platforms
iOS
JavaScript runtime
Hermes
Workflow
React Native
Architecture
Fabric (New Architecture)
Build type
Debug app & dev bundle
Device
iOS simulator
Device model
iPad Air 11-inch (M2)
Acknowledgements
Yes
Screenshots