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

KeyboardAwareScrollView not working on first load of the app after fresh install in production iOS builds #338

Closed
domenicoprestia opened this issue Jan 19, 2024 · 42 comments
Assignees
Labels
🐛 bug Something isn't working 📚 components Anything related to the exported components of this library 🍎 iOS iOS specific KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component

Comments

@domenicoprestia
Copy link

domenicoprestia commented Jan 19, 2024

Describe the bug

First of all i want to thank you for the great work you've put in in this repo, it's a gamechanger.

I've a form that needs to be inside a KeyboardAwareScrollView, everytime i open the keyboard i've a button that remains sticky to the header of the keyboard (it works well on the first load after a fresh install).

The strange behaviour is that when i update or i install the application on my device (iPhone 12 Pro) the KeyboardAwareScrollView doesnt scroll how it should preventing the keyboard from covering the focused input.

If i reload the app it works fine.

Code snippet

<View>

  <KeyboardAwareScrollView
    bottomOffset={88}
    ref={scrollRef}
    onScroll={scrollHandler}
    onContentSizeChange={callbackContentSizeChange}
    showsVerticalScrollIndicator={false}
    keyboardShouldPersistTaps={'handled'}
    keyboardDismissMode={'on-drag'}
  >
    <RecipeFormTitle
      step={step}
      setStep={setStep}
      paddingBottom={headerPaddingBottom}
      paddingTop={headerHeight}
      scrollValue={scrollValue}
    />
    {renderFormStep}
  </KeyboardAwareScrollView>
</View>

<RecipeFormFooter
  onContinue={callbackContinue}
  onBack={callbackBack}
  step={step}
  disabled={disabled} />


<KeyboardFloatingCTA
  onPress={callbackPressFloatingCTA}
  text={textFloatingCTA}
  disabled={disabledFloatingCTA}
  icon={iconFLoatingCTA}
/>

<ModalTagsConfirmation bottomSheetModalRef={modalTagsConfirmationRef} onContinue={callbackContinueForce} />
<ModalStepsConfirmation bottomSheetModalRef={modalSingleStepConfirmationRef} onContinue={callbackContinueForce} />
<ModalChallengeConfirmation bottomSheetModalRef={modalIngredientsChallengeConfirmationRef}onConfirm={callbackContinueForce}  />
<ModalPhotoChallengeConfirmation bottomSheetModalRef={modalPhotoChallengeConfirmationRef} onConfirm={callbackContinueForce} />
<ModalFailedImageUpload bottomSheetModalRef={modalFailedImageUploadRef} />

;

Repo for reproducing

The code is private, i cant share it with you sadly.

Expected behavior

The KeyboardAwareScrollView should work as expected on the first load of the app.

Screenshots

RPReplay_Final1705679938.MP4

Smartphone (please complete the following information):

  • Desktop OS: [MacOS 14.2.1]
  • Device: [iPhone 12 Pro]
  • OS: [16.2]
  • RN version: [0.72.6]
  • RN architecture: [paper]
  • JS engine: [Hermes]
  • Library version: [1.10.2]

Additional context
Add any other context about the problem here.

@kirillzyusko kirillzyusko added 🐛 bug Something isn't working 🍎 iOS iOS specific 📚 components Anything related to the exported components of this library labels Jan 19, 2024
@kirillzyusko
Copy link
Owner

Okay @domenicoprestia thank you for the issue. I'll look into it 👀

@hyochan
Copy link

hyochan commented Apr 5, 2024

Hi @kirillzyusko, I've encountered a critical issue with the app. Upon initial installation, the keyboard fails to display. However, it starts working as expected if I force quit the app and then restart it. This could significantly impact the experience of new users. Could you please look into this?

@kirillzyusko
Copy link
Owner

@hyochan is this problem reproducible in example app? It fails to display on iOS or Android? Without this library everything works fine?

Can you provide a minimal reproduction example so that I can look into it?

@hyochan
Copy link

hyochan commented Apr 6, 2024

@kirillzyusko This seems to be a time-intensive task. I'll do my best, but please understand that I can't make any promises.

@domenicoprestia
Copy link
Author

Hi @kirillzyusko in my case, it fails only on ios, and the keyboard is actually showing but the KeyboardAwareScrollView is not scrolling when keyboard is opened.

After killing and reopening the app everything is on place and works just fine

@kirillzyusko
Copy link
Owner

@domenicoprestia were you able to reproduce this problem in example app? 🤔

@domenicoprestia
Copy link
Author

i have to distribute it on the store to reproduce this :I

@kirillzyusko
Copy link
Owner

@domenicoprestia so you're saying that locally it works fine (even if you assemble a release build and open it from mobile), but if you download the same app from AppStore then KeyboardAwareScrollView is not working?..

@domenicoprestia
Copy link
Author

I've not tried to resemble a build locally, i've only tried it on the simulator with metro, but when i try it from the versions on AppDistribution or on TestFlight the KeyboardAwareScrollView, on iOS, on first launch does not work, i will try to reproduce it on a local build an i will let you know

@domenicoprestia
Copy link
Author

I will try to build locally and put it on the simulator asap and i will let you know

@kawasakime
Copy link

Same problem. Everything worked correctly for me, both when building on an iPhone (debug) and in the emulator. But when my colleague starts the project, the KeyboardAwareScrollView component does not work. But if you close the application completely and open it again, it starts working. It has this behavior both in the emulator and when building in TestFlight.

@kirillzyusko
Copy link
Owner

kirillzyusko commented May 14, 2024

@kawasakime can you please describe step by step what I need to do to make it reproducible? Is it reproducible in simulator? If yes, then what I need to make to make it reproducible?

Do I need to assemble app and push it into TestFlight and only then I can reproduce the problem? Do I need to pay 99$ for that (to be able to upload app in the store/TestFlight)?

@kawasakime
Copy link

@kawasakime can you please describe step by step what I need to do to make it reproducible? Is it reproducible in simulator? If yes, then what I need to make to make it reproducible?

Do I need to assemble app and push it into TestFlight and only then I can reproduce the problem? Do I need to pay 99$ for that (to be able to upload app in the store/TestFlight)?

This is the problem, that we do not understand what this is connected with. Everything worked fine for me, but a colleague has the same problem as described in this issue. At first we couldn’t even understand why the component wasn’t working. We tried to change props and perform other manipulations but nothing helped. Then he tried to close the application from the running list (without turning off the metro console) and opened it again in the emulator - and lo and behold, the component worked. Then we tried to start the project from scratch again (closed metro and started it again), and again the component did not work until we completely closed the application again and opened it again

@kirillzyusko
Copy link
Owner

kirillzyusko commented May 14, 2024

@kawasakime okay, that means that at least you have a decent reproduction example (the laptop of your colleague). What happens if you add console.log here (line 270)?

onMove: (e) => {
"worklet";
const keyboardFrame = interpolate(
Is it executed?

If it works (i. e. handler gets called) can you log additional params, such as e, layout.value and scrollViewTarget.value, height - keyboardHeight.value and (layout.value?.layout.absoluteY || 0) + layout.value?.layout.height || 0.

Just to understand why exactly scrollTo is not getting called.

@kirillzyusko kirillzyusko added the KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component label May 29, 2024
@vladanzlatar
Copy link

in my case this only happens when I first open in app browser to login with google and KeyboardAwareScrollView is non responsive, specifically onMove is not even called, but onStart and onEnd are called and log this:

"onStart", {
  "e": { // event
    "duration": 250,
    "eventName": "75onKeyboardMoveStart",
    "height": 336,
    "progress": 1,
    "target": 2619
  },
  "heightCalc": 852, // height - keyboardHeight.value
  "heightCalc2": 0, // (layout.value?.layout.absoluteY || 0) + layout.value?.layout.height || 0
  "layoutValue": null, // layout.value
  "scrollViewTargetValue": 2769 // scrollViewTarget.value
}

"onEnd", {
  "e": {
    "duration": 250,
    "eventName": "75onKeyboardMoveEnd",
    "height": 336,
    "progress": 1,
    "target": 2619
  },
  "heightCalc": 516,
  "heightCalc2": 635,
  "layoutValue": {
    "eventName": "75onFocusedInputLayoutChanged",
    "layout": {
      "absoluteX": 36,
      "absoluteY": 585,
      "height": 50,
      "width": 321,
      "x": 12,
      "y": 0
    },
    "parentScrollViewTarget": 2769,
    "target": 2619
  },
  "scrollViewTargetValue": 2769
}

if I open app and first try to open keyboard(instead of first opening in app browser) then KeyboardAwareScrollView works fine, so the conclusion for my case is that there is some problem with in app browser and react-native-keyboard-controller. I am using @aws-amplify/rtn-web-browser for in app browser google oauth

@kirillzyusko
Copy link
Owner

@vladanzlatar interesting. Probably the algorithm for detecting keyboard doesn't work when there is a new window gets attached/detached 🤔

@vladanzlatar is it possible to create a small reproduction example? Maybe it works not only with google authentication (I believe for that you'll have to add tokens into reproduction example and most likely you will not want to do that) but with other pages too (like google.com)? I've never worked with aws-amplify stack in RN, and may do something incorrect 🙈 So if you can help me to prepare a small reproduction example - that would be simply amazing and will significantly speed up the fix process!

@vladanzlatar
Copy link

@kirillzyusko sure I'll try to provide some in app browser example probably with https://www.npmjs.com/package/react-native-inappbrowser-reborn and see if this is actually a cause.

Do you have in mind some recommendation for quick fix since my team needs it as soon as possible and I am not quite sure what can I do to maybe "restart" KeyboardAwareScrollView or lib state so that after google oauth keyboard works fine

@kirillzyusko
Copy link
Owner

@vladanzlatar the quick fix would probably be to set a focus to TextInput and hide it. But it might cause layout jumps 😔

Maybe try to set focus to input and then hide it when SplashScreen is visible?..

@kirillzyusko
Copy link
Owner

@vladanzlatar thank you for pointing out to the issue - I've reproduced the problem in example app as well.

Here is a diff in hierarchy.

Without browser (1x UITextEffectsWindow):

image

With browser (2x UITextEffectsWindow):

image

Because of that my KeyboardView.find() can not detect a keyboard. I'll fix it (hopefully within this week and publish a new version) 🤞

@vladanzlatar
Copy link

that's great news 🙌 🤞, I am not sure if this is also the reason issue happens to the OP(@domenicoprestia) since I can't reproduce it without browser

@kirillzyusko
Copy link
Owner

kirillzyusko commented Jun 13, 2024

@vladanzlatar may I kindly ask you to apply a patch from this PR #471 to your local project and tell me if it fixes the problem in your project?

@vladanzlatar
Copy link

vladanzlatar commented Jun 13, 2024

@kirillzyusko I updated to:

    "react-native-keyboard-controller": "github:kirillzyusko/react-native-keyboard-controller#fix/keyboard-view-is-not-detectable",

but nothing, I've done rm -rf node_modules ios and then reinstalled and built so I am not quite sure if there are any cache issues since issue still exists

@kirillzyusko
Copy link
Owner

kirillzyusko commented Jun 13, 2024

@vladanzlatar can you check the implementation of KeyboardView.find method (https://github.com/kirillzyusko/react-native-keyboard-controller/blob/main/ios/traversal/KeyboardView.swift#L14)? Does it look like from the PR or like in main branch?

P. S. did you reinstall pods? 👀

@vladanzlatar
Copy link

@kirillzyusko it's like from the PR and yes I've reinstall the pods 🤷‍♂️

@kirillzyusko
Copy link
Owner

@vladanzlatar okay, it's strange. I could reproduce the problem successfully but with this fix in place everything works fine 🤔
I guess I only can wait a reproduction from you and then I can work on fixing this problem 😓

BTW here is my discord - if you want we can chat there 👀

@vladanzlatar
Copy link

vladanzlatar commented Jun 13, 2024

@kirillzyusko sure we can chat via discord, just not sure how to add you since that link just opens my DM(all I know is that I can add you through username)

@kirillzyusko
Copy link
Owner

@vladanzlatar my nickname is kiryl.ziusko (#8496)

If you can not find me, then you can share your profile 👀

kirillzyusko added a commit that referenced this issue Jun 14, 2024
## 📜 Description

Handle corner case when keyboard view is not detectable on iOS.

## 💡 Motivation and Context

Sometimes app may have more than one `UITextEffectsWindow` and nested
`UIInputSetContainerView` may not have a children (as on a screenshot):

<img width="344" alt="image"
src="https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/d67fa4f1-bc5d-458a-8814-2bd0103940c6">

In this case our previous code would return `nil` and full library
functionality would be broken. From a screenshot above it's clear, that
we should continue our search.

So to fix the problem I removed one `break` signal (loop over windows).
Thus if we encounter empty `UIInputSetContainerView` we will continue
search and will go to the next window (which will return a correct
reference to the keyboard view).

Additionally I added `return` statement when we found a view (before 3
break statements served for this purpose, but since I removed one - the
order is slightly broken, so to keep better backward compatibility and
don't execute additional cycles if view was found - I used `return`
statement there).

See the context when we may have more than one `UITextEffectsWindow` in
#338 (comment)

## 📢 Changelog

<!-- High level overview of important changes -->
<!-- For example: fixed status bar manipulation; added new types
declarations; -->
<!-- If your changes don't affect one of platform/language below - then
remove this platform/language -->

### iOS

- removed `break` inside iteration over windows
- added `return` to exit from `for` loops immediately 
- refactored code and removed variable creation

## 🤔 How Has This Been Tested?

Tested on iPhone 15 Pro (iOS 17.5).

## 📸 Screenshots (if appropriate):

|Before|After|
|-------|-----|
|<video
src="https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/5e608b41-5849-443e-97a1-f9d1c7304400">|<video
src="https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/98156771-1ffa-447e-8ed3-6a123903737a">|

## 📝 Checklist

- [x] CI successfully passed
- [x] I added new mocks and corresponding unit-tests if library API was
changed
kirillzyusko added a commit that referenced this issue Jun 14, 2024
## 📜 Description

Ignore non visible keyboard in `KeyboardView.find()` method.

## 💡 Motivation and Context

Sometimes we may have two keyboards:


![image](https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/52456847-f1fd-4cd6-a21a-81a5afd8d6c8)

And the current algorithm for a search returns an invalid keyboard (not
a one that is actually shown on the screen):


![image](https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/fc22c83d-95c5-41de-9893-a4399330264b)

or


![image](https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/c00f411e-d690-4f7a-bddf-a28c0a732381)

But when actual keyboard is tracked, then the frame of this keyboard has
non-zero height:


![image](https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/15c0ce28-f8c4-4c96-ad1f-35236a08e49e)

So to fix the problem with invalid keyboard view being found I decided
to modify a condition and add additional condition to check that
`frame.height != 0`.

Follow up for
#471
and
#338 (comment)

## 📢 Changelog

<!-- High level overview of important changes -->
<!-- For example: fixed status bar manipulation; added new types
declarations; -->
<!-- If your changes don't affect one of platform/language below - then
remove this platform/language -->

### iOS

- ignore keyboard view if its `height == 0`;

## 🤔 How Has This Been Tested?

Tested on CI (e2e tests).

## 📝 Checklist

- [x] CI successfully passed
- [x] I added new mocks and corresponding unit-tests if library API was
changed
@kirillzyusko
Copy link
Owner

@domenicoprestia @hyochan @kawasakime @vladanzlatar I published 1.12.3 - can you check if it fixes the problem for you? 👀

@vladanzlatar
Copy link

@kirillzyusko for me it is fixed with #473 🙌

@subhyde
Copy link

subhyde commented Aug 16, 2024

@vladanzlatar was there anything else you did to resolve this? I am having the exact same issue as @domenicoprestia

@kirillzyusko
Copy link
Owner

@subhyde we were chatting in Discord with @vladanzlatar (he could reproduce the issue locally with attached XCode debugger) and were trying to understand what is going wrong (and eventually we found the root problem and fixed it).

@subhyde can you reproduce the problem locally (without downloading an app from App Store)? Can you attach XCode debugger when the problem is reproducible?

@subhyde
Copy link

subhyde commented Aug 16, 2024

@kirillzyusko I am having no issues using expo go, or development builds. It works flawlessly.

The keyboard awareness is partially working on both preview and production builds, installed through expo / test flight. It grants extra space to the user so if the text field is closer to the bottom of page so they can scroll and view the field without it being obstructed.

However, the scroll to is not working, when i tap on a field, it does not automatically scroll and bring the field into view.

I forgot to mention that I am using this in a Modal, if that makes any difference!

@kirillzyusko
Copy link
Owner

I forgot to mention that I am using this in a Modal, if that makes any difference!

Hm, potentially can be a case!

However, the scroll to is not working, when i tap on a field, it does not automatically scroll and bring the field into view.

So, it happens only in builds downloaded from TestFlight? What happens if you build a release version of the app locally via XCode (without uploading a build to TestFlight)?

@theJovian
Copy link

Hi, I'm experience a similar behavior using debug and release builds. The first time I open my app, my textInputs are hidden behind the keyboard, but after navigating to another screen they work just fine even if I navigate back to the previous screen where they behaved wrong. In my case this only happens in versions >= 13.0.0. For previous versions the library works great. Btw, I'm using RN 0.75.1

@kirillzyusko
Copy link
Owner

@theJovian can you check if the issue you are talking about is fixed by #575? 👀 According to the description of the issue I believe it should be fixed by these changes 😅

Let me know if it's not!

@theJovian
Copy link

@theJovian can you check if the issue you are talking about is fixed by #575? 👀 According to the description of the issue I believe it should be fixed by these changes 😅

Let me know if it's not!

Seems like it's the same issue yeah! I'll wait for the next release to check it out then, thaanks.

@ng-ha
Copy link

ng-ha commented Sep 29, 2024

i got the same issue, KeyboardAwareScrollView works as expected in iPhone SE, but it doesn't work on newer iPhone like 15 (simulator and real device). I believe that this happens only in versions >= 1.13. Previous version (specifically 1.12.5) works fine! @kirillzyusko

@kirillzyusko
Copy link
Owner

@ng-ha may I ask you to provide a minimal reproduction example? In my example project everything works fine, so it's really hard for me to say what exactly causes the problem 🤷‍♂️ Have you tried to use latest (1.13.4) version?

@ng-ha
Copy link

ng-ha commented Oct 1, 2024

@kirillzyusko I am using latest version. I found what caused the bug: if you wrap KeyboardAwareScrollView with a View that has marginHorizontal, KeyboardAwareScrollView doesn't work in iPhone 15:

Not working

 <View style={{marginHorizontal: 12}}>
      <KeyboardAwareScrollView
        alwaysBounceVertical={false}
        showsVerticalScrollIndicator={false}
        keyboardShouldPersistTaps="handled"
        bottomOffset={120}>
      ...
      </KeyboardAwareScrollView>
    </View>

Working

      <KeyboardAwareScrollView
        alwaysBounceVertical={false}
        showsVerticalScrollIndicator={false}
        keyboardShouldPersistTaps="handled"
        contentContainerStyle={{marginHorizontal: 12}}
        bottomOffset={120}>
      ...
      </KeyboardAwareScrollView>

@kirillzyusko
Copy link
Owner

@ng-ha in my example external padding works. I use this code:

    <View style={{marginHorizontal: 12}}>
      <KeyboardAwareScrollView
        bottomOffset={50}
        alwaysBounceVertical={false}
        showsVerticalScrollIndicator={false}
        keyboardShouldPersistTaps="handled"
        enabled={enabled}
        testID="aware_scroll_view_container"
      >

Video:

Simulator.Screen.Recording.-.iPhone.15.Pro.-.2024-10-07.at.22.59.25.mp4

Any ideas what is the difference between our setup? 👀

@kirillzyusko
Copy link
Owner

test-fligh-ios-18-3.mp4

@domenicoprestia I uploaded an application (example app) to test flight, but it works even after first launch. I tested iOS 15.9 and iOS 18.0.1

Have you tried to test recent versions (1.14.5)? I think the problem can be solved in recent versions 🤔 Can you please confirm, that the bug still exist or can I close the issue?

@kirillzyusko
Copy link
Owner

I'm going to close this issue, since I didn't get a reproduction example and many fixes since then were made and I believe one of those fixes could fix the problem 🙂

If anyone is experiencing the same problem - please provide as much details as you can and open a new issue with reference to this issue 👀 If you can prepare a reproduction example - that would be simply amazing 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug Something isn't working 📚 components Anything related to the exported components of this library 🍎 iOS iOS specific KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component
Projects
None yet
Development

No branches or pull requests

8 participants