mateusz1913 / react-native-avoid-softinput

Native solution for common React Native problem of focused views being covered by soft input view.
https://mateusz1913.github.io/react-native-avoid-softinput/
MIT License
700 stars 18 forks source link

[ios] On iOS keyboard focusing/dismissal will very ocassionally cause the root view to shrink its height #86

Closed fobos531 closed 1 year ago

fobos531 commented 2 years ago

Environment

Library version: 2.4.6 OS version: iPhone 8, iOS 15.5 & iOS 16.0

This has also happened on v2.4.4 of the library and I can confirm that the app behaves as intended when I remove the library from the project.

I have most commonly seen this behaviour on iPhone models with the home button.

Affected platforms

Current behavior

Sometimes, very very ocassionally, random interactions with the UI - most commonly those interactions are blurring/focusing textfields, dismissing/expanding keyboard but I think it can happen elsewhere too - will cause the root view to shrink its height to half the height of the screen. See the attached picture: CleanShot 2022-08-05 at 19 18 23

Expected behavior

The root view's height should not shrink.

Reproduction

To be honest, I really, really have no clue how to reproduce this issue. It seems to be entirely random and unpredictable, and hence I cannot identify the reproduction steps to reproduce it reliably. If there's anything else I can do, or information I can provide to help reproduce this issue, let me know.

mateusz1913 commented 2 years ago

Hi @fobos531, I understand that it may be very rare issue, but still I don't have enough information to even start debugging.

The bare minimum would be:

Additionally, it would be nice to have at least a video with a reproduction.

Also it would be awesome to see where the user touches - on iOS it can be done e.g. with ShowTime (requires Swift), or FingerTips (you can install it as a package or even copy files directly as it is done in Reanimated example app - https://github.com/software-mansion/react-native-reanimated/tree/main/Example/ios look for MBFingerTipWindow.[h/m])

fobos531 commented 2 years ago

Hey! Thanks for getting back about this issue.

I'll try to provide some more context right off the bat, but as soon as I get more time, I'll try to make a reproducible example (which probably won't be for another month or so :/ )

is it occurring when using module or AvoidSoftInputView? I'm using both in my code, so I would say that they both may play a role in this. This issue also doesn't necessarily occur when the screen that uses the View/module is in focus, but can also happen when a screen which doesn't use the module/views directly. Though I do enable this library via the module on app start in an useEffect.

is it occurring for text input that is placed inside any scroll view? Yes, it mostly happens when interacting with text inputs which are inside of a scrollview 99% of time.

is animation config customized (any delays, or duration changed)? Yes, I useually tweak the hide animation duration&delay as well as the show animation duration.

is it triggered by jumping between inputs with different keyboard type? No, I don't think so.

What I found curious is that this tends to happens when "mixing" native stack navigator and stack navigator from react-navigation inside the app. My setup is basically using native-stack navigators everywhere in my app, except for the components that make use of the react-native-bottom-sheet library - those use the JS-based navigators. I discovered that as soon as I migrated the entirety of my app to use the JS-based navigators everywhere (without any native-stack navigators), the issue went away. Thought this piece of info might be useful.

intergalacticspacehighway commented 1 year ago

Thanks for the library @mateusz1913. It's working really well!

I managed to reproduce this issue. It's happening with React navigation modal for me. There's a ScrollView and TextInput outside of ScrollView.

https://user-images.githubusercontent.com/23293248/192970479-414531f8-64d0-4c23-a437-d3f941c5d374.mov

With some debugging, I found that it calls setOffsetInRootView but I guess detected root view changes in between the transition and the offset gets applied to the outer root view 🤔

You can checkout the code in this branch. Happy to help with testing!

mateusz1913 commented 1 year ago

Hi @intergalacticspacehighway, thx for your input. I think I managed to make a similar use case in the repo's example (although I use react-navigation with native stack modals). Could you test if the following fix works for you?

diff --git a/packages/react-native-avoid-softinput/ios/AvoidSoftInputManager.swift b/packages/react-native-avoid-softinput/ios/AvoidSoftInputManager.swift
index fe53911..7edbddc 100644
--- a/packages/react-native-avoid-softinput/ios/AvoidSoftInputManager.swift
+++ b/packages/react-native-avoid-softinput/ios/AvoidSoftInputManager.swift
@@ -257,6 +257,13 @@ class AvoidSoftInputManager: NSObject {
         }

         private func removeOffsetInRootView(rootView: UIView) {
+            if rootView.frame.origin.y == 0 {
+                // https://github.com/mateusz1913/react-native-avoid-softinput/issues/86
+                // If we are here, it means that the view which had offset applied was probably unmounted.
+                // This can happen e.g. when user interactively dismiss iOS modal screen in react-navigation
+                // (I reproduced it in Native Stack, but the issue reporters had it in JS Stack - both use react-native-screens under the hood)
+                return
+            }
             let initialRootViewFrameOriginY = rootView.frame.origin.y
             beginHideAnimation(initialOffset: bottomOffset, addedOffset: -bottomOffset)
             UIView.animate(

@fobos531 are you able to test it in your case as well? If it will work, then I'll commit the fix for v3 (3.0.1) and also v2 (2.4.8)

fobos531 commented 1 year ago

Hey @mateusz1913 , unfortunately I'm not able to test this as I've migrated away from this library on a mission-critical app, but I'm looking forward to using it in future projects if needed and testing there 👍

intergalacticspacehighway commented 1 year ago

@mateusz1913 Thanks for the quick fix! 🙏 Can confirm that it's working well.

mateusz1913 commented 1 year ago

Awesome, I'll push it and try to make a patch releases in the evening

mateusz1913 commented 1 year ago

This fix is merged and available in versions v3.0.1 & v2.4.8 🚀