Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS][KeyboardAvoidingView] Using KeyboardAvoidingView inside a ScrollView causes the app the crash when focusing an input #42939

Open
slauzinho opened this issue Feb 9, 2024 · 40 comments
Labels

Comments

@slauzinho
Copy link

slauzinho commented Feb 9, 2024

Description

When KeyboardAvoidingView inside a ScrollView and focus a TextInput the app crashes (goes extremely slow).

This seems to only happen if the KeyboardAvoidingView needs to trigger the animation, if the ScrollView is small it works fine.

Testing with react native 0.72.9 the issue doesn't seem to happen

Steps to reproduce

  1. install the app yarn ios
  2. Using the simulator make sure the keyboard shows when entering a text input
  3. Focus a text input and start typing on the keyboard
  4. Dismiss the keyboard / click outside of the input
  5. You will notice the app has now hung

React Native Version

0.73.4

Affected Platforms

Runtime - iOS

Output of npx react-native info

System:
  OS: macOS 14.2.1
  CPU: (10) arm64 Apple M1 Max
  Memory: 127.84 MB / 32.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.18.2
    path: ~/.nvm/versions/node/v18.18.2/bin/node
  Yarn:
    version: 1.22.21
    path: ~/.nvm/versions/node/v18.18.2/bin/yarn
  npm:
    version: 9.8.1
    path: ~/.nvm/versions/node/v18.18.2/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.14.3
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.2
      - iOS 17.2
      - macOS 14.2
      - tvOS 17.2
      - visionOS 1.0
      - watchOS 10.2
  Android SDK: Not Found
IDEs:
  Android Studio: 2021.1 AI-211.7628.21.2111.8309675
  Xcode:
    version: 15.2/15C500b
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.9
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.73.4
    wanted: 0.73.4
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false


### Stacktrace or Logs

```text
Excessive number of pending callbacks: 501. Some pending callbacks that might have leaked by never being called from native code: {"235":{"module":"UIManager","method":"configureNextLayoutAnimation"},"238":{"module":"UIManager","method":"configureNextLayoutAnimation"},"241":{"module":"UIManager","method":"configureNextLayoutAnimation"},"244":{"module":"UIManager","method":"configureNextLayoutAnimation"},"247":{"module":"UIManager","method":"configureNextLayoutAnimation"},"250":{"module":"UIManager","method":"configureNextLayoutAnimation"},"253":{"module":"UIManager","method":"configureNextLayoutAnimation"},"256":{"module":"UIManager","method":"configureNextLayoutAnimation"},"259":{"module":"UIManager","method":"configureNextLayoutAnimation"},"262":{"module":"UIManager","method":"configureNextLayoutAnimation"},"265":{"module":"UIManager","method":"configureNextLayoutAnimation"},"268":{"module":"UIManager","method":"configureNextLayoutAnimation"},"271":{"module":"UIManager","method":"configureNextLayoutAnimation"},"274":{"module":"UIManager","method":"configureNextLayoutAnimation"},"277":{"module":"UIManager","method":"configureNextLayoutAnimation"},"280":{"module":"UIManager","method":"configureNextLayoutAnimation"},"283":{"module":"UIManager","method":"configureNextLayoutAnimation"},"286":{"module":"UIManager","method":"configureNextLayoutAnimation"},"289":{"module":"UIManager","method":"configureNextLayoutAnimation"},"292":{"module":"UIManager","method":"configureNextLayoutAnimation"},"295":{"module":"UIManager","method":"configureNextLayoutAnimation"},"298":{"module":"UIManager","method":"configureNextLayoutAnimation"},"301":{"module":"UIManager","method":"configureNextLayoutAnimation"},"304":{"module":"UIManager","method":"configureNextLayoutAnimation"},"307":{"module":"UIManager","method":"configureNextLayoutAnimation"},"310":{"module":"UIManager","method":"configureNextLayoutAnimation"},"313":{"module":"UIManager","method":"configureNextLayoutAnimation"},"316":{"module":"UIManager","method":"configureNextLayoutAnimation"},"319":{"module":"UIManager","method":"configureNextLayoutAnimation"},"322":{"module":"UIManager","method":"configureNextLayoutAnimation"},"325":{"module":"UIManager","method":"configureNextLayoutAnimation"},"328":{"module":"UIManager","method":"configureNextLayoutAnimation"},"331":{"module":"UIManager","method":"configureNextLayoutAnimation"},"334":{"module":"UIManager","method":"configureNextLayoutAnimation"},"337":{"module":"UIManager","method":"configureNextLayoutAnimation"},"340":{"module":"UIManager","method":"configureNextLayoutAnimation"},"343":{"module":"UIManager","method":"configureNextLayoutAnimation"},"346":{"module":"UIManager","method":"configureNextLayoutAnimation"},"349":{"module":"UIManager","method":"configureNextLayoutAnimation"},"352":{"module":"UIManager","method":"configureNextLayoutAnimation"},"355":{"module":"UIManager","method":"configureNextLayoutAnimation"},"358":{"module":"UIManager","method":"configureNextLayoutAnimation"},"361":{"module":"UIManager","method":"configureNextLayoutAnimation"},"364":{"module":"UIManager","method":"configureNextLayoutAnimation"},"367":{"module":"UIManager","method":"configureNextLayoutAnimation"},"370":{"module":"UIManager","method":"configureNextLayoutAnimation"},"373":{"module":"UIManager","method":"configureNextLayoutAnimation"},"376":{"module":"UIManager","method":"configureNextLayoutAnimation"},"379":{"module":"UIManager","method":"configureNextLayoutAnimation"},"382":{"module":"UIManager","method":"configureNextLayoutAnimation"},"...(truncated keys)...":451}


### Reproducer

https://github.com/slauzinho/KeyboardAvoidingViewExample

### Screenshots and Videos



https://github.com/facebook/react-native/assets/445345/72aa333e-f55a-446f-aea5-6b7615b8a4ca

@alfonsocj
Copy link
Collaborator

@lunaleaps I can reproduce this issue using the reproducer mentioned in the description https://github.com/slauzinho/KeyboardAvoidingViewExample.

@cortinico cortinico added the Issue: Author Provided Repro This issue can be reproduced in Snack or an attached project. label Feb 9, 2024
@kokosky93
Copy link

kokosky93 commented Feb 11, 2024

@cortinico same issue.

Moving KeyboardAvoidingView over a ScrollView fixed my problem with crashing application when clicking on an input (IOS)

The crash was happening when publishing the app and on real device.

Guideline 2.1 - Performance - App Completeness

We discovered one or more bugs in your app. Specifically, login screen was unresponsive. Please review the details below and complete the next steps.

Review device details:

  • Device type: iPad Air (5th generation)
  • OS version: iOS 17.3.1

@Hasanraza786
Copy link

Kindly check this key in scrollview
overScrollMode='never'
@kokosky93

@slauzinho
Copy link
Author

Kindly check this key in scrollview overScrollMode='never' @kokosky93

overScrollMode is an Android prop shouldn't really matter in this case

@kokosky93
Copy link

That's true. Setting overScrollMode didn't help.

@zaferatli
Copy link

i dont think its crash, its loop cause mis-use of element. in this case keyboardawarescroll in scrollview; when keyboard is open its trigger to keyboardawarescroll to extend bottom height and put keyboard down and thats circle trigger to scrollview because layout change and also scrollview extends layout and keyboardawarescroll again try to put keyboard to bottom so extend layout and again triggered scrollview.

Even i prevent this loop keyboardawarescroll its not working properly, can't arrange keyboard position and content because scrollview.

Related part KeyboardAvoidingView.js:

   // update bottom height for the first time or when the height is changed
    if (!oldFrame || oldFrame.height !== this._frame.height) {
      await this._updateBottomIfNecessary();
    }

@tomerh2001
Copy link

Any updates? Also experiencing this - v0.73.4

@Navaie
Copy link

Navaie commented Feb 26, 2024

Experiencing the same issue here! RN v0.73.4 as well. The issue indeed seems to be related to being inside a ScrollView, and on top having the behaviour set to padding, like so:
<KeyboardAvoidingView behavior="padding">

When setting the behaviour to position, there is no problem.
<KeyboardAvoidingView behavior="position">

Edit: added more details

@mcoeur
Copy link

mcoeur commented Feb 27, 2024

I tried @Navaie's solution.
It seems to be a bit more stable but crashes anyway when fiddling with the input + scrollview.
For now, we're removing KeyboardAvoidingViews completely

@mpringlehlk
Copy link

Like @kokosky93 , my workaround was to swap the component order to make the KeyboardAvoidingView the parent element of the ScrollView, then add a new child View for applying container styles that were previously on the KeyboardAvoidingView.

So far, everything seems to be working as intended.

I also observed that this issue only affected distributions running on real iOS devices. Not reproducible in either ExpoGo or Android builds.

@marvinfok
Copy link

Experiencing the same issue here! RN v0.73.4 as well. The issue indeed seems to be related to being inside a ScrollView, and on top having the behaviour set to padding, like so: <KeyboardAvoidingView behavior="padding">

When setting the behaviour to position, there is no problem. <KeyboardAvoidingView behavior="position">

Edit: added more details

Thanks buddy! Works! Yes, must change behavior to ="position", else will not scroll.

@nehresma
Copy link

We were running into this as well and have temporarily removed the KeyboardAvoidingView that was triggering this.

@jasenpashov
Copy link

Thanks

@janoslc
Copy link

janoslc commented Apr 5, 2024

Experienced the same thing, I had <KeyboardAvoidingView/> inside of a <SafeAreaView/>. It works on the iOS Emulator, on Android simulator and device, it only "freezes" on real iOS device. I'm following this conversation now.

"react-native": "0.73.6"

@ericTrayt
Copy link

Experiencing the same thing here as well. 0.73.6

@ajakka
Copy link

ajakka commented Apr 22, 2024

Any updates in regards to this issue?

@shahidrogers
Copy link

shahidrogers commented Apr 23, 2024

I'm facing this same issue too, using <KeyboardAvoidingView/> inside of a <SafeAreaView/>.

It only freezes on a real iOS device (not all iOS devices either, so far I've been able to reproduce this issue on iPhone SE running latest iOS) - but unable reproduce on simulator/android.

Update: Flipping the sequence so that SafeAreaView is encapsulated by KeyboardAvoidingView seems to resolve it - confirmed after testing.

"react-native": "0.73.7"

@ajakka
Copy link

ajakka commented Apr 24, 2024

@shahidrogers If the issue happens solely because of the <SafeAreaView/>, then you can try to use the useSafeAreaInsets hook instead.

alanupstone added a commit to Helpful-Consultants/PocketInfowebSDK46 that referenced this issue Apr 30, 2024
@slauzinho
Copy link
Author

Still happens with react native 0.74.1

@joshzeldin
Copy link

I think I’m experiencing something similar with TextInput inside of a KeyboardAvoidingView on react native 0.74.1.

@olofd
Copy link

olofd commented May 28, 2024

Same here.. 0.74.1

@safee-cases
Copy link

Same issue here. Problem seems to appear only on "small" device: working perfectly on iPhone 11, crashing on iPhone 13 mini.

I'm currently trying to implement this PR in local before it get merged:

#44652

@yummyelin
Copy link

yummyelin commented Jun 27, 2024

Same issue here. Problem seems to appear only on "small" device: working perfectly on iPhone 11, crashing on iPhone 13 mini.

I'm currently trying to implement this PR in local before it get merged:

#44652

tried this change locally, seems not working for me. v0.73.8

@patrickkeenan
Copy link

Glad this is being fixed. Its super frustrating because it only appears when uploaded to test flight. I couldn't reproduce the error in my development build.

@JB712
Copy link

JB712 commented Jul 29, 2024

Same issue here. Problem seems to appear only on "small" device: working perfectly on iPhone 11, crashing on iPhone 13 mini.

I'm currently trying to implement this PR in local before it get merged:

#44652

I think I'm facing the same issue with an iPad (10th gen) and an iPhone 11 so not only small devices. Besides, I have an iPhone 15 that doesn't encounter this bug.
I'm working with react-native@0.73.9

Edit: my problem might not be completely related to this so don't rely too much on it but while I was fixing my issue i discovered that I had packed ScrollView into ScrollView (nestedScrollEnabled={false}) into KeyboardAvoidingView into ScrollView into KeyboardAvoidingView. I did fix this disaster to have only ScrollV into KeyboardAV, but I noticed somewhere else where it remains a SV into KAV into SV into KAV and it doesn't bug/freeze so ¯\_(ツ)_/¯

@Jmzp
Copy link

Jmzp commented Aug 21, 2024

I have the same problem in iOS with RN .73.9.

@maratkarelov
Copy link

I have the same problem in iOS with RN .73.9.

remove KeyboardAvoidingView

@DnEgorWeb
Copy link

Hey guys, anyone knows alternative to KeyboardAvoidingView?

@fz6m
Copy link

fz6m commented Aug 23, 2024

move ScrollView inside KeyboardAvoidingView , it works for me

@fstefanello
Copy link

I found a simple example where I can reproduce a similar issue on the Android emulator. I'm not sure, but I believe the problem is related.

The issue occurs when the position of the KeyboardAvoidingView is above the size of the keyboard. This causes the KeyboardAvoidingView component to keep increasing the padding indefinitely.

render() {
  return (
    <View>
      <View style={{borderWidth: 1, height: DEVICE_HEIGHT - 200}}/>
      <KeyboardAvoidingView behavior='padding'>
        <TextInput style={{borderWidth: 1}} />
      </KeyboardAvoidingView>
    </View>
  );
}

@matinzd
Copy link
Contributor

matinzd commented Aug 23, 2024

We've encountered this issue on some real iOS devices, despite using both SafeAreaView and KeyboardAvoidingView in our React Native app.

To address this, I'm planning to switch to Keyboard Controller and replace SafeAreaView with the corresponding hook. I'll release an update to see if this resolves the problem.

It's challenging to debug since I haven't been able to reproduce the issue on my end.

@cipolleschi, could you assist with this? It feels like a regression that's been around in RN for a while.

Environment:

  • react-native: 0.74.5
  • New architecture: off

@matinzd
Copy link
Contributor

matinzd commented Aug 26, 2024

Removing SafeAreaView and using keyboard controller fixed the issue and we verified it with one of our customers. I still can't reproduce it on my end.

@kubiisimsek
Copy link

Hi guys

I have the same problem with rn 0.73.9 on iOS real device in production and scheme build config:Release on simulator. It worried me but solved.

<ScrollView>
    <KeyboardAvoidingView behavior={Platform.OS == "ios" ? "paddding":null}>
    ...
    </KeyboardAvoidingView>
</ScrollView>

If KeyboardAvoidingView inside the ScrollView with prop behavior="padding" in iOS,screen is freezes.
I change behavior padding to position for ios it worked but screen bounced when typing.

Using it belows everything worked for me.

<KeyboardAvoidingView behavior={Platform.OS == "ios" ? "paddding":null}>
  <ScrollView>
   ...
   </ScrollView>
</KeyboardAvoidingView>

Some said above that it was caused by SafeAreaView. My SafeAreaView defined in App.js. In my project, it's not because of it.

I hope it'll fixed.

@cipolleschi
Copy link
Contributor

Hello there, I'm sorry that you are encountering this issue.
I see that this is happening with the Old Architecture. Is it happening also with the New Architecture?

At the moment we are hyper focused on rolling out the New Architecture, so issues for the Old Architecture only has lower priority as they will move capacity away from our final goal.

@omgaz
Copy link

omgaz commented Sep 3, 2024

@cipolleschi We're seeing this issue too across old and new devices; we've just upgraded to "react-native": "0.73.8" and are only seeing it on 'real' ios devices.

Screenshot 2024-09-03 at 14 34 13

Similar to #42939 (comment), we're getting it on SafeAreaView; we'll see if we can flip it too and see what happens.

@cipolleschi
Copy link
Contributor

I'm looking into this, and I see that the app get blocked and eventually crashes.
However, this bug is only happening in the Old Architecture, so sadly I can't spend more time on this as we should focus on the New Architecture.

To unblock on this, I actually think that you should not use the <KeyboardAvoidingView> component inside a scrollview. If what you want to scroll is the scrollview, the <ScrollView> component has the prop automaticallyAdjustKeyboardInsets that should fix the issue on the Old Architecture.
It should also work in the New Architecture.

@mkhotib20
Copy link

move ScrollView inside KeyboardAvoidingView , it works for me

me too, you can move it. it works

@matinzd
Copy link
Contributor

matinzd commented Sep 16, 2024

@cipolleschi How did you reproduce it?

@cipolleschi
Copy link
Contributor

@matinzd with the reproducer attached to the issue:
https://github.com/slauzinho/KeyboardAvoidingViewExample

@johnnywang
Copy link

johnnywang commented Nov 8, 2024

Been debugging an issue with our app freezing on certain screens only in real iOS 17.5+ devices, and finally narrowed it down to this same issue here that people have been reporting.

Some details:

  • We have a KeyboardAvoidingView inside a SafeAreaView, but this still happens even if I switch to using the hook, or dropping safe area logic entirely
  • Only happens when the behavior is set to "padding" (though anything else breaks the UI)
  • Only seems to happen (100% consistently) on real iOS 17 (possibly only 17.5+) devices
  • Does not happen / cannot repro on emulators
  • Does not crash the app, and no errors reported anywhere, but freezes entirely and necessitates a hard close/restart
  • Ejected Expo 51.0.38
  • React Native 0.75.4

@cipolleschi while I understand the prioritization of the new architecture right now, I'd argue that there are probably a good number of teams and products still using older versions of RN. Even for those of us who are on the newer versions where we can opt into the new architecture, there are a lot of third party packages and dependencies that don't support the new architecture yet, which leaves us in a tough spot because "just upgrade to the new architecture" is not a solution. (And as a few others have also reported, it's not just a ScrollView / SafeArea issue)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests