facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
119.25k stars 24.34k forks source link

Keyboard Flickering on TextInput with secureTextEntry #39411

Closed gcon97 closed 1 year ago

gcon97 commented 1 year ago

Description

If you have 2 text inputs, (One with secure text entry enabled and the other set to disabled), When typing, highlighting and scrolling in the non-secure text entry, the keyboard will flicker. This is an iOS issue only, I have tested this using iOS 17, on an iPhone 13 mini. I cannot repeat this issue in the simulator, only on the device.

It appears to be when iOS recognizes it as a login field, so it presents the auto-fill passwords UI. See the attached video on the flickering issue described.

https://github.com/facebook/react-native/assets/33269267/d0222621-afc8-4090-a0c8-9dcdb7d35bcb

React Native Version

0.72.4

Output of npx react-native info

System: OS: macOS 13.4.1 CPU: (10) arm64 Apple M1 Pro Memory: 115.16 MB / 16.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 20.3.1 path: /opt/homebrew/bin/node Yarn: version: 1.22.19 path: /usr/local/bin/yarn npm: version: 9.6.7 path: /opt/homebrew/bin/npm Watchman: version: 2023.06.12.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.11.3 path: /usr/local/bin/pod SDKs: iOS SDK: Platforms:

Steps to reproduce

Have 2 TextInput components inside a view, one set with secureTextEntry, one without.

This issue is only seen on device, not in simulator

Snack, screenshot, or link to a repository

https://github.com/gcon97/KeyboardFlickeringDemo

tianlinjill commented 1 year ago

I also encountered the similar issue when in login screen

ShadReyes commented 1 year ago

I am experiencing the same on login screens. It's a newer issue. It seems to be caused by the suggested autofill.

The problem is reduce by using default value prop passed to TextInput component that holds its own text ref and passes out ref value on change.

ShadReyes commented 1 year ago

I figured out the problem

It appears to be that at some point recently (pre iOS 17) a bug was introduced. Whenever secureTextEntry={false} and textContentType is set, various Text Input changes (typing, focus, etc...) will fire a native keyboardWillChangeFrame event that causes the keyboard to re-render. This also causes iOS's AutoFill QuickType Bar (forgive me if my terminology is incorrect) to flicker.

This can be especially problematic for any RN apps using KeyboardAvoidingView with iOS behavior={'position'} since it will cause a layout flicker as it adjusts to the disappearing and reappearing AutoFill QuickType Bar.

You can actually see the issue in native iOS apps:

  1. Go to the login screen of a native iOS app.
  2. Change focus from username and password fields.
  3. In many apps you can see a slight bounce as the keyboard animations handle the AutoFill QuickType Bar flicker.

For those who are using KeyboardAvoidingView (RN V0.72.* Patch Fix)

For those who are wrapping their text inputs in a <KeyboardAvoidingView behavior= 'position'}> and <ScrollView>, you are likely dealing with your screen jumping on text change and focus change.

This isn't a pretty solution (and keep in mind it does not fix the root issue of the keyboard re-render), but you can do the following **TEMPORARY and NOT fully tested** fix for this issue:

  1. Go to the file at: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
  2. Add ignoreIOSKeyboardWillChangeEvents?: boolean | undefined; to the KeyboardAvoidingView props.
  3. Go to the types file at: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts
  4. Add ignoreIOSKeyboardWillChangeEvents?: boolean | undefined; to the KeyboardAvoidingView props.
  5. Replace the const {duration, easing, endCoordinates} = this._keyboardEvent; line with the following:
    
    const {duration, easing, endCoordinates} = this._keyboardEvent;

if(Platform.OS === 'ios' && duration === 0 && !!this.props.ignoreIOSKeyboardWillChangeEvents ) { return; }


6. Use patch package to save the changes.

be sure to set `ignoreIOSKeyboardWillChangeEvents={true}` with care. I, for example, am only using it on a login screen for a very specific keyboard avoiding use case scenario that I detail above. Hope this helps.
ThorANilsson commented 1 year ago

https://github.com/facebook/react-native/assets/138024148/7af7cc86-ba82-4b90-b77e-c4be9b1796cf

I began seeing this after updating the device i test on (iPhone 14 Pro) to iOS 17. Using Expo Go. Very annoying...

What's interesting is that I am not experiencing this on another iPhone 11 Pro Max, also running iOS 17.

ThorANilsson commented 1 year ago

I believe this is caused by the "Passwords"-thing (see attached image) that appears on iOS when the OS believes you want to use a password from your keychain.

When I test on a phone that does not have a keychain, there is no jumping or flickering. IMG-4401

gcon97 commented 1 year ago

I can confirm that it is an issue with the Passwords option in the Keyboard toolbar. Seems to be an issue across iOS 17 rather than a ReactNative issue. (It also isn't fixed in iOS 17.1, so we may be waiting a while for a fix).

Closing as it isn't a React Native-specific issue.

ThorANilsson commented 1 year ago

Adding textContentType='oneTimeCode' to your TextInput disables the Password toolbar, which also eliminates the described issue.

Shubham0850 commented 1 year ago

@ThorANilsson I tried this, but it's not working for me.

mkhoussid commented 1 year ago

Here's what I did.

TL;DR: If it's a password field, on each change update the actual string value in a map, and then render the value as bullets ('•'). What we're essentially doing here is saying that all of our fields are just regular fields without autofill, but we can manipulate the value of the field, if it's a password field, if we pass a certain flag.

Somewhere created a file called maskMap.ts with the following:

export const maskMap = new Map<string, string>();

And in your custom TextField component (I'm assuming most of you have wrapped TextInput into one of your own TextField components):

import * as React from 'react';
import { TextInput } from 'react-native-paper';
import { maskMap } from './maskMap';

const PASSWORD_MASK_CHAR = '•';
. . .
// secureTextEntry determines whether or not this is a password field
const TextField = React.memo(({ onChange, secureTextEntry, ...props }: YourTextFieldProps) => {
  const [textFieldId] = React.useState(uuid()); // use whatever uuid generator you'd like
. . .
  React.useEffect(() => {
      maskMap.set(textFieldId, '');

      return () => {
          maskMap.delete(textFieldId);
      };
  }, [secureTextEntry]);

  const handleChange = React.useCallback((e: string) => {
      if (secureTextEntry) {
          const previousValue = maskMap.get(textFieldId) as string;
          const formattedNewValue = e.replace(new RegExp(PASSWORD_MASK_CHAR, 'g'), '');

          const newValue = previousValue + formattedNewValue;
          onChange(newValue);
          maskMap.set(textFieldId, previousValue + formattedNewValue);
      } else {
          onChange(e);
      }
  }, [secureTextEntry]);

  const getValue = React.useCallback(() => {
      if (!secureTextEntry) {
          return value;
      }

      return value.replaceAll(/./g, PASSWORD_MASK_CHAR);
  }, [value, secureTextEntry, showText, maskMap]);
. . .

    return (
        . . .
            <TextInput
                value={getValue()}
                onChangeText={handleChange}
                textContentType='none' // add this
                . . .
            />
        . . .
    )
})
Engazan commented 12 months ago

how this can be closed if its still happening ?

it happends all the time when you have textContentType="password" or secureTextEntry

ShadReyes commented 12 months ago

@Engazan It's closed because it's an iOS bug. iOS started over-triggering keyboardWillChangeFrame events every time the input changes when the arguments you specified are implemented. We can't ignore this event because it's relied on for many component designs and reactivity. So, sadly we have to put in temporary patch fixes until Apple fixes it on their side.

noahkurz commented 12 months ago

Adding textContentType='oneTimeCode' to your TextInput disables the Password toolbar, which also eliminates the described issue.

This works! Thank you!! Just saved my weekend lol

chimiWangchukWangdi commented 11 months ago

Any updates

nguyenhuynhdeveloper commented 10 months ago

I have found the solution. The error is caused by props value , you can hide the value and handle the logic with ref Screenshot 2024-01-02 at 16 19 22 ![Uploading Screenshot 2024-01-02 at 16.19.22.png…]()

nnphong1904 commented 10 months ago

Hi everyone, is there any update on this?

xydian commented 9 months ago

Also happening on my side :) Seems to be an issue in flutter, too https://github.com/flutter/flutter/issues/134723

FemtDeveloper commented 9 months ago

I have problem also in android,, can somebody helpme?

https://github.com/facebook/react-native/assets/7281791/5cdfed29-6aec-4f47-bad4-fd0c97d3e508

ugar0ff commented 9 months ago

How to hide the "password" panel on the keyboard when we use secureTextEntry?

Dinexpod commented 8 months ago

Hi there! On iOS 17.3.1 problem still exists.

On iOS lower version all works fine.

Bialson commented 8 months ago

The problem still exist on iOS 17.4

chrysb commented 8 months ago

Can confirm this is happening on 17.4, on an email field for me, despite the type being emailAddress:

autoCapitalize='none'
autoComplete='email'
textContentType='emailAddress'
keyboardType='email-address'
Bialson commented 8 months ago

I've found in my case problem was caused by value prop. I'am using react-hook-form and if I pass value of email input from hook directly to email input it calls keyboard event on every single character input. After removing prop, everything works fine.

loe-lobo commented 8 months ago

I've found in my case problem was caused by value prop. I'am using react-hook-form and if I pass value of email input from hook directly to email input it calls keyboard event on every single character input. After removing prop, everything works fine.

@Bialson, how do you manage the field's value in this case? I'm facing the same problem, and it is driving me crazy.

<Controller
            name="email"
            defaultValue=""
            control={control}
            rules={{
              validate: async (value) => {
                try {
                  await signInSchema.parseAsync({ email: value });
                  return true;
                } catch (error: any) {
                  return error.message;
                }
              },
            }}
            render={({ field: { onChange, onBlur, value } }) => (
              <Input>
                <InputField
                  fontSize="$sm"
                  placeholder="Email"
                  type="text"
                  value={value}
                  onChangeText={onChange}
                  onBlur={onBlur}
                  onSubmitEditing={handleKeyPress}
                  returnKeyType="done"
                />
              </Input>
            )}
          />

If I remove the prop value={value}, it gets better, not 100%, but it flickers much less. But then how would you clean the input?

Thanks in advance

chrysb commented 8 months ago

In addition to this flickering issue, it seems that in 17.4, when you try to tap a specific character in a TextInput to put the cursor at the middle of the string, it always jumps to the end of the TextInput.

https://github.com/facebook/react-native/assets/120388/154a4f13-f66e-46ce-a46b-f120f55fc097

It even happens on the official react native demo (if you use the QR code to open in Expo): https://reactnative.dev/docs/textinput

Is this also an iOS issue and not a RN issue @gcon97

HannahCarney commented 8 months ago

If you add multline={true} to the email field that fixed it for me. So then I thought okay it's just to do with height, so I set a fixed height on both of my inputs, and the flickering when typing is gone but it still flickers when you change fields but I think that's because I have two different types of input.

Bialson commented 8 months ago

@Bialson, how do you manage the field's value in this case? I'm facing the same problem, and it is driving me crazy.

<Controller
            name="email"
            defaultValue=""
            control={control}
            rules={{
              validate: async (value) => {
                try {
                  await signInSchema.parseAsync({ email: value });
                  return true;
                } catch (error: any) {
                  return error.message;
                }
              },
            }}
            render={({ field: { onChange, onBlur, value } }) => (
              <Input>
                <InputField
                  fontSize="$sm"
                  placeholder="Email"
                  type="text"
                  value={value}
                  onChangeText={onChange}
                  onBlur={onBlur}
                  onSubmitEditing={handleKeyPress}
                  returnKeyType="done"
                />
              </Input>
            )}
          />

If I remove the prop value={value}, it gets better, not 100%, but it flickers much less. But then how would you clean the input?

Thanks in advance

@loe-lobo You can declare reference to input and when needed use clear() method from ref object to clear the value of input. I have been struggling with flickering for a long period and for me, this is the best temporary solution. I think there is a problem with unnecessary re-render, some native event is triggering, which isn't supposed to execute when value changes.

MickaelAustoni commented 8 months ago

Try to add autoCorrect={false} to avoid Flickering on TextInput render

<TextInput 
  autoCorrect={false} 
  ...
/>
Sovent commented 7 months ago

I have this issue on iPhone 17.3.1 It happens on email field, but not on password one (regardless of whether I set keyboard type or not). Autocorrect solution did not work for me and I'd rather not go to other hacky stuff like setting it to multiline or changing node modules manually. I see that AirBnb login form does not have this issue on the same device, so there must be a way to handle this flickering from code. Please reopen this issue

MickaelAustoni commented 7 months ago

I have this issue on iPhone 17.3.1 It happens on email field, but not on password one (regardless of whether I set keyboard type or not). Autocorrect solution did not work for me and I'd rather not go to other hacky stuff like setting it to multiline or changing node modules manually. I see that AirBnb login form does not have this issue on the same device, so there must be a way to handle this flickering from code. Please reopen this issue

autoCorrect={false} should be set only on your email input and dont forgot to reload your app when you test.

jstarmx commented 7 months ago

I figured out the problem

It appears to be that at some point recently (pre iOS 17) a bug was introduced. Whenever secureTextEntry={false} and textContentType is set, various Text Input changes (typing, focus, etc...) will fire a native keyboardWillChangeFrame event that causes the keyboard to re-render. This also causes iOS's AutoFill QuickType Bar (forgive me if my terminology is incorrect) to flicker.

This can be especially problematic for any RN apps using KeyboardAvoidingView with iOS behavior={'position'} since it will cause a layout flicker as it adjusts to the disappearing and reappearing AutoFill QuickType Bar.

You can actually see the issue in native iOS apps:

  1. Go to the login screen of a native iOS app.
  2. Change focus from username and password fields.
  3. In many apps you can see a slight bounce as the keyboard animations handle the AutoFill QuickType Bar flicker.

For those who are using KeyboardAvoidingView

For those who are wrapping their text inputs in a <KeyboardAvoidingView behavior= 'position'}> and <ScrollView>, you are likely dealing with your screen jumping on text change and focus change.

This isn't a pretty solution (and keep in mind it does not fix the root issue of the keyboard re-render), but you can do the following **TEMPORARY and NOT fully tested** fix for this issue:

  1. Go to the file at: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
  2. Add ignoreIOSKeyboardWillChangeEvents?: boolean | undefined; to the KeyboardAvoidingView props.
  3. Go to the types file at: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts
  4. Add ignoreIOSKeyboardWillChangeEvents?: boolean | undefined; to the KeyboardAvoidingView props.
  5. Replace the const {duration, easing, endCoordinates} = this._keyboardEvent; line with the following:
const {duration, easing, endCoordinates} = this._keyboardEvent;

if(Platform.OS === 'ios' && duration === 0 && !!this.props.ignoreIOSKeyboardWillChangeEvents ) {
      return;
}
  1. Use patch package to save the changes.

be sure to set ignoreIOSKeyboardWillChangeEvents={true} with care. I, for example, am only using it on a login screen for a very specific keyboard avoiding use case scenario that I detail above. Hope this helps.

The only solution that worked for me without negative effects, thanks.

Darren120 commented 7 months ago

I figured out the problem

It appears to be that at some point recently (pre iOS 17) a bug was introduced. Whenever secureTextEntry={false} and textContentType is set, various Text Input changes (typing, focus, etc...) will fire a native keyboardWillChangeFrame event that causes the keyboard to re-render. This also causes iOS's AutoFill QuickType Bar (forgive me if my terminology is incorrect) to flicker.

This can be especially problematic for any RN apps using KeyboardAvoidingView with iOS behavior={'position'} since it will cause a layout flicker as it adjusts to the disappearing and reappearing AutoFill QuickType Bar.

You can actually see the issue in native iOS apps:

  1. Go to the login screen of a native iOS app.
  2. Change focus from username and password fields.
  3. In many apps you can see a slight bounce as the keyboard animations handle the AutoFill QuickType Bar flicker.

For those who are using KeyboardAvoidingView (RN V0.72.* Patch Fix)

For those who are wrapping their text inputs in a <KeyboardAvoidingView behavior= 'position'}> and <ScrollView>, you are likely dealing with your screen jumping on text change and focus change.

This isn't a pretty solution (and keep in mind it does not fix the root issue of the keyboard re-render), but you can do the following **TEMPORARY and NOT fully tested** fix for this issue:

  1. Go to the file at: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
  2. Add ignoreIOSKeyboardWillChangeEvents?: boolean | undefined; to the KeyboardAvoidingView props.
  3. Go to the types file at: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts
  4. Add ignoreIOSKeyboardWillChangeEvents?: boolean | undefined; to the KeyboardAvoidingView props.
  5. Replace the const {duration, easing, endCoordinates} = this._keyboardEvent; line with the following:
const {duration, easing, endCoordinates} = this._keyboardEvent;

if(Platform.OS === 'ios' && duration === 0 && !!this.props.ignoreIOSKeyboardWillChangeEvents ) {
      return;
}
  1. Use patch package to save the changes.

be sure to set ignoreIOSKeyboardWillChangeEvents={true} with care. I, for example, am only using it on a login screen for a very specific keyboard avoiding use case scenario that I detail above. Hope this helps.

2024 and still using this workaround...

1989kumarsunil commented 6 months ago

@ThorANilsson solution worked for me. set textContentType='oneTimeCode' prop in textinput. Thanks

matheuscostadesign commented 6 months ago

Has anyone found any solution for the keyboard to keep the password suggestion without flickering?

1989kumarsunil commented 6 months ago

Has anyone found any solution for the keyboard to keep the password suggestion without flickering?

Please check my above comment. One solution worked for me. Thanks

matheuscostadesign commented 6 months ago

Has anyone found any solution for the keyboard to keep the password suggestion without flickering?

Please check my above comment. One solution worked for me. Thanks

@1989kumarsunil With textContentType="oneTimeCode" it partially solved the problem. The keyboard has stopped flickering, but the password suggestion is not being displayed. I want to keep the suggestion, as many users use password management applications and need this functionality...

ShadReyes commented 6 months ago

Has anyone found any solution for the keyboard to keep the password suggestion without flickering?

Please check my above comment. One solution worked for me. Thanks

@1989kumarsunil With textContentType="oneTimeCode" it partially solved the problem. The keyboard has stopped flickering, but the password suggestion is not being displayed. I want to keep the suggestion, as many users use password management applications and need this functionality...

@matheuscostadesign From what I understand, there is no current solution that completely fixes the flickering problem. Above I have described a solution when in an avoiding view to stop view jumping, but it does not stop the flickering. This problem is the result of an iOS bug, but I will be looking into an updated temporary hack-fix soon. I will post the patch in here when it is complete.

one1two2 commented 6 months ago

Is this problem exist in new major version 73.X, 74.X?

RedSwiftDev commented 6 months ago

... textContentType='none' ...

not working on iOS 17+

Ashutosh26121999 commented 6 months ago

I figured out the problem

It appears to be that at some point recently (pre iOS 17) a bug was introduced. Whenever secureTextEntry={false} and textContentType is set, various Text Input changes (typing, focus, etc...) will fire a native keyboardWillChangeFrame event that causes the keyboard to re-render. This also causes iOS's AutoFill QuickType Bar (forgive me if my terminology is incorrect) to flicker.

This can be especially problematic for any RN apps using KeyboardAvoidingView with iOS behavior={'position'} since it will cause a layout flicker as it adjusts to the disappearing and reappearing AutoFill QuickType Bar.

You can actually see the issue in native iOS apps:

  1. Go to the login screen of a native iOS app.
  2. Change focus from username and password fields.
  3. In many apps you can see a slight bounce as the keyboard animations handle the AutoFill QuickType Bar flicker.

For those who are using KeyboardAvoidingView (RN V0.72.* Patch Fix)

For those who are wrapping their text inputs in a <KeyboardAvoidingView behavior= 'position'}> and <ScrollView>, you are likely dealing with your screen jumping on text change and focus change.

This isn't a pretty solution (and keep in mind it does not fix the root issue of the keyboard re-render), but you can do the following **TEMPORARY and NOT fully tested** fix for this issue:

  1. Go to the file at: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
  2. Add ignoreIOSKeyboardWillChangeEvents?: boolean | undefined; to the KeyboardAvoidingView props.
  3. Go to the types file at: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts
  4. Add ignoreIOSKeyboardWillChangeEvents?: boolean | undefined; to the KeyboardAvoidingView props.
  5. Replace the const {duration, easing, endCoordinates} = this._keyboardEvent; line with the following:
const {duration, easing, endCoordinates} = this._keyboardEvent;

if(Platform.OS === 'ios' && duration === 0 && !!this.props.ignoreIOSKeyboardWillChangeEvents ) {
      return;
}
  1. Use patch package to save the changes.

be sure to set ignoreIOSKeyboardWillChangeEvents={true} with care. I, for example, am only using it on a login screen for a very specific keyboard avoiding use case scenario that I detail above. Hope this helps.

Uploading Screen-recording-20240501-122505.mp4…

ashirkhan94 commented 6 months ago

Adding textContentType='oneTimeCode' to your TextInput disables the Password toolbar, which also eliminates the described issue.

Thanks @ThorANilsson

Engazan commented 6 months ago

Btw with iOS 17.5 and expo SDK 51 I don't see this issue in my apps ( they are gone )

TalhaZmr7 commented 5 months ago

Adding textContentType='oneTimeCode' to your TextInput disables the Password toolbar, which also eliminates the described issue.

Thank you for saving my Day. <3

a-petrenko-muse commented 5 months ago

Thanks for textContentType='oneTimeCode'

I hope apple fixes this

https://github.com/facebook/react-native/assets/134932472/1dccf5fe-f3e5-42a0-a3cd-c6f28396b9bb

FemtDeveloper commented 5 months ago

My main issue was a continuous state update on a screen that wasn't focused, causing the app to continuously rerender.

ludersGabriel commented 5 months ago

problem still exists. The textContentType="oneTimeCode" solves it, but removes the password autofill option.

GGraciet commented 5 months ago

I figured out the problem

It appears to be that at some point recently (pre iOS 17) a bug was introduced. Whenever secureTextEntry={false} and textContentType is set, various Text Input changes (typing, focus, etc...) will fire a native keyboardWillChangeFrame event that causes the keyboard to re-render. This also causes iOS's AutoFill QuickType Bar (forgive me if my terminology is incorrect) to flicker.

This can be especially problematic for any RN apps using KeyboardAvoidingView with iOS behavior={'position'} since it will cause a layout flicker as it adjusts to the disappearing and reappearing AutoFill QuickType Bar.

You can actually see the issue in native iOS apps:

  1. Go to the login screen of a native iOS app.
  2. Change focus from username and password fields.
  3. In many apps you can see a slight bounce as the keyboard animations handle the AutoFill QuickType Bar flicker.

For those who are using KeyboardAvoidingView (RN V0.72.* Patch Fix)

For those who are wrapping their text inputs in a <KeyboardAvoidingView behavior= 'position'}> and <ScrollView>, you are likely dealing with your screen jumping on text change and focus change.

This isn't a pretty solution (and keep in mind it does not fix the root issue of the keyboard re-render), but you can do the following **TEMPORARY and NOT fully tested** fix for this issue:

  1. Go to the file at: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
  2. Add ignoreIOSKeyboardWillChangeEvents?: boolean | undefined; to the KeyboardAvoidingView props.
  3. Go to the types file at: node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts
  4. Add ignoreIOSKeyboardWillChangeEvents?: boolean | undefined; to the KeyboardAvoidingView props.
  5. Replace the const {duration, easing, endCoordinates} = this._keyboardEvent; line with the following:
const {duration, easing, endCoordinates} = this._keyboardEvent;

if(Platform.OS === 'ios' && duration === 0 && !!this.props.ignoreIOSKeyboardWillChangeEvents ) {
      return;
}
  1. Use patch package to save the changes.

be sure to set ignoreIOSKeyboardWillChangeEvents={true} with care. I, for example, am only using it on a login screen for a very specific keyboard avoiding use case scenario that I detail above. Hope this helps.

Also works for me, but instead of editing files in node_modules, I've created a custom KeyboardAvoidingView class component that extends original KeyboardAvoidingView component. So this "temporary" fix will still be applied if dependencies are re-installed (eg. using a CI in specific env to build).

(As it looks like TS doesn't support props overriding in a class component inheritance pattern, @ts-nocheck is needed at top of file to avoid TS errors.)

// @ts-nocheck
import {
  LayoutAnimation,
  Platform,
  KeyboardAvoidingView as RNKeyboardAvoidingView,
  KeyboardAvoidingViewProps as RNKeyboardAvoidingViewProps,
} from "react-native";

export interface KeyboardAvoidingViewProps extends RNKeyboardAvoidingViewProps {
  ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
}

export default class KeyboardAvoidingView extends RNKeyboardAvoidingView {
  constructor(props: KeyboardAvoidingViewProps) {
    super(props);
  }

  _updateBottomIfNecessary = async () => {
    if (this._keyboardEvent == null) {
      this.setState({ bottom: 0 });
      return;
    }

    const { duration, easing, endCoordinates } = this._keyboardEvent;

    if (
      Platform.OS === "ios" &&
      duration === 0 &&
      !!this.props.ignoreIOSKeyboardWillChangeEvents
    ) {
      return;
    }

    const height = await this._relativeKeyboardHeight(endCoordinates);

    if (this.state.bottom === height) {
      return;
    }

    if (duration && easing) {
      LayoutAnimation.configureNext({
        // We have to pass the duration equal to minimal accepted duration defined here: RCTLayoutAnimation.m
        duration: duration > 10 ? duration : 10,
        update: {
          duration: duration > 10 ? duration : 10,
          type: LayoutAnimation.Types[easing] || "keyboard",
        },
      });
    }
    this.setState({ bottom: height });
  };
}
deekstone commented 4 months ago

Try this simple solution :)

           <TextInput
           ...
            multiline  
            returnKeyType="done"
            blurOnSubmit
          />
arjunmehta commented 4 months ago

Try this simple solution :)

           <TextInput
           ...
            multiline  
            returnKeyType="done"
            blurOnSubmit
          />

@deekstone This worked for me, except in my case I used "next" for returnKeyType. Thank you!

Garett-MacGowan commented 4 months ago

Still no real solution. Disabling passwords autofill with textContentType="oneTimeCode", using multiline, or overriding KeyBoardAvoidingView is slop.

deekstone commented 4 months ago

Still no real solution. Disabling passwords autofill with textContentType="oneTimeCode", using multiline, or overriding KeyBoardAvoidingView is slop.

no one said this is a permanent fix, but its the only one that works with less code.