Replies: 1 comment 2 replies
-
Hello, creator of
If I understand correctly you want to wrap entire app in kind of
As you pointed out before such approach also will come with its own set of challenges. We'll need to send a corresponding update to shadow nodes, virtualised lists also must be notified about changes, etc. Initially when I just started with designing
After considering all nuances I decided to give a try and implement a first approach just because a communication with JS might be needed anyway and you (as a developer) have a more control over it. Thanks to reanimated we can propagate all these events to ScreenRecording_01-16-2025.11-26-05.AM_1.MP4At least on iOS modifying padding/height seems to work fine. On Android I can see a delay but I think it's an Android limitation (Android experts feel free to correct me). May I ask you where exactly you experience a problem using And last but not least - the solution "let's move everything to native using native primitives" may not always work fine and come with its own limitations. For example I'm not saying that your proposed solution is bad, just trying to understand what exactly can not be fixed by current ecosystem, whether it's possible to fix current ecosystem to support your use-case and trying to anticipate further challenges with a new approach 🙂 |
Beta Was this translation helpful? Give feedback.
-
Avoiding the on-screen keyboard on iOS is a challenge. There are many options, including React Native's
KeyboardAvoidingView
;ScrollView
optionautomaticallyAdjustKeyboardInsets
, Reanimated'suseAnimatedKeyboard
, andreact-native-keyboard-controller
. All the aforementioned options rely on keyboard notifications to follow the keyboard. Since iOS moved to an out-of-process model, notifications are now delivered asynchronously (Keep up with the keyboard - WWDC23), which has resulted in various issues. For example, theUIKeyboardWillShowNotification
notification does not always include an accurate end frame. Library authors have put workarounds in place, but each iOS update is a chance for potential regressions which have to be tracked down and fixed.iOS 15 introduced the Keyboard Layout Guide. The Keyboard Layout Guide makes it incredibly easy to track the on-screen keyboard. However, since it is constraint based, it is not compatible with React Native's layout model out of the box. Supporting the Keyboard Layout Guide in React Native would be beneficial as it supports all "detached" keyboard types (undocked, split and floating); does not require coordinate space conversion to support Slide Over and Stage Manager; and does does not share the notification issues that impact current implementations. Using the Keyboard Layout Guide would also make it possible to introduce configuration similar to Android's
windowSoftInputMode
option, with support for bothadjustPan
andadjustResize
.I have had some luck using the Keyboard Layout Guide in my app. I created an Expo Module that provides an alternative
KeyboardAvoidingView
. The native code takes the children and adds them to a container subview. It then sets constraints on that subview, with the containerbottomAnchor
constrained to thekeyboardLayoutGuide
topAnchor
when the keyboard isnear
the bottom of the screen (necessary to support the Shortcuts Bar). When the keyboard is opened, because the containerheightAnchor
is constrained to theKeyboardAvoidingView
component height, the container subview is shifted along the Y-axis. In order to keep the scroll view content accessible, I setcontentInset
andscrollIndicatorInsets
on theUIScrollView
. This is similar to theautomaticallyAdjustKeyboardInsets
implementation, except the entire view is shifted upwards in addition to setting insets.Most things seem to work fine with this approach. For example,
measure
andmeasureInWindow
both use native methods and as such, are aware of the shift in the Y axis. However,measureLayout
relies on the shadow tree layout, and is not aware of the shift (as is documented). Another downside of this approach is that theScrollView
and subsequentlyFlatList
are not aware of the portion of content that is off-screen.scrollToIndex
withviewPosition
is inaccurate, andFlatList
viewability callbacks provide incorrect information. However,automaticallyAdjustKeyboardInsets
is subject to the same issues.Alternatively, I have found that the bounds observer is called immediately just as the keyboard is about to open -- and the corresponding view also has an active animation. I was able to send this into JavaScript and animate padding of the
KeyboardAvoidingView
. However, there is a delay, and the animation lags a few frames behind the keyboard. React Native'sKeyboard
observer has the same issue. Unfortunately the performance of interactive dismissal is also pretty poor, since the keyboard height is being sent from native to JS and then back to native to update the padding.This is where I need help. I think the latter option is likely the best way forward. If there were a way to update the
KeyboardAvoidingView
padding from the native side, we could wrap that update inUIView.animate
and there should be no lag. Updating interactive dismissal padding in native would also be desirable, to avoid the round trip to JS. However, I'm not sure how to do this, or if it's even possible.From there, we could either implement a
KeyboardAvoidingView
that works similar to today -- where the views are added as children and the keyboard is avoided with padding. Alternatively, the entire React Native app could be wrapped andsetFrame
used to send the constrained height into React Native. However, this is all beyond what I understand so I would love some feedback on how best to proceed.Beta Was this translation helpful? Give feedback.
All reactions