react-native icon indicating copy to clipboard operation
react-native copied to clipboard

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

Open slauzinho opened this issue 6 months ago • 24 comments

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

slauzinho avatar Feb 09 '24 10:02 slauzinho

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

alfonsocj avatar Feb 09 '24 12:02 alfonsocj

@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

kokosky93 avatar Feb 11 '24 21:02 kokosky93

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

Hasanraza786 avatar Feb 12 '24 11:02 Hasanraza786

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

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

slauzinho avatar Feb 13 '24 19:02 slauzinho

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

kokosky93 avatar Feb 14 '24 08:02 kokosky93

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();
    }

zaferatli avatar Feb 15 '24 22:02 zaferatli

Any updates? Also experiencing this - v0.73.4

tomerh2001 avatar Feb 21 '24 17:02 tomerh2001

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

Navaie avatar Feb 26 '24 13:02 Navaie

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

mcoeur avatar Feb 27 '24 08:02 mcoeur

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.

mpringlehlk avatar Feb 28 '24 20:02 mpringlehlk

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.

marvinfok avatar Mar 02 '24 09:03 marvinfok

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

nehresma avatar Mar 20 '24 15:03 nehresma

Thanks

jasenpashov avatar Apr 01 '24 06:04 jasenpashov

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"

janoslc avatar Apr 05 '24 05:04 janoslc

Experiencing the same thing here as well. 0.73.6

ericTrayt avatar Apr 11 '24 15:04 ericTrayt

Any updates in regards to this issue?

ajakka avatar Apr 22 '24 11:04 ajakka

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"

shahidrogers avatar Apr 23 '24 02:04 shahidrogers

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

ajakka avatar Apr 24 '24 18:04 ajakka

Still happens with react native 0.74.1

slauzinho avatar May 14 '24 14:05 slauzinho

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

joshzeldin avatar May 22 '24 14:05 joshzeldin

Same here.. 0.74.1

olofd avatar May 28 '24 20:05 olofd

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:

https://github.com/facebook/react-native/pull/44652

safee-cases avatar May 29 '24 10:05 safee-cases

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

yummyelin avatar Jun 27 '24 20:06 yummyelin

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.

patrickkeenan avatar Jul 10 '24 01:07 patrickkeenan

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 [email protected]

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 ¯\_(ツ)_/¯

JB712 avatar Jul 29 '24 14:07 JB712