Closed gcon97 closed 1 year ago
I also encountered the similar issue when in login screen
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.
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:
AutoFill QuickType Bar
flicker.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:
node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
to the KeyboardAvoidingView props.node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts
ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
to the KeyboardAvoidingView props.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.
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.
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.
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.
Adding textContentType='oneTimeCode'
to your TextInput disables the Password toolbar, which also eliminates the described issue.
@ThorANilsson I tried this, but it's not working for me.
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
. . .
/>
. . .
)
})
how this can be closed if its still happening ?
it happends all the time when you have textContentType="password"
or secureTextEntry
@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.
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
Any updates
I have found the solution. The error is caused by props value , you can hide the value and handle the logic with ref ![Uploading Screenshot 2024-01-02 at 16.19.22.png…]()
Hi everyone, is there any update on this?
Also happening on my side :) Seems to be an issue in flutter, too https://github.com/flutter/flutter/issues/134723
I have problem also in android,, can somebody helpme?
https://github.com/facebook/react-native/assets/7281791/5cdfed29-6aec-4f47-bad4-fd0c97d3e508
How to hide the "password" panel on the keyboard when we use secureTextEntry?
Hi there! On iOS 17.3.1 problem still exists.
On iOS lower version all works fine.
The problem still exist on iOS 17.4
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'
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.
I've found in my case problem was caused by
value
prop. I'am usingreact-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
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
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, 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.
Try to add autoCorrect={false}
to avoid Flickering on TextInput
render
<TextInput
autoCorrect={false}
...
/>
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
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.
I figured out the problem
It appears to be that at some point recently (pre iOS 17) a bug was introduced. Whenever
secureTextEntry={false}
andtextContentType
is set, various Text Input changes (typing, focus, etc...) will fire a nativekeyboardWillChangeFrame
event that causes the keyboard to re-render. This also causes iOS'sAutoFill QuickType Bar
(forgive me if my terminology is incorrect) to flicker.This can be especially problematic for any RN apps using
KeyboardAvoidingView
with iOSbehavior={'position'}
since it will cause a layout flicker as it adjusts to the disappearing and reappearingAutoFill QuickType Bar
.You can actually see the issue in native iOS apps:
- Go to the login screen of a native iOS app.
- Change focus from username and password fields.
- 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:
- Go to the file at:
node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
- Add
ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
to the KeyboardAvoidingView props.- Go to the types file at:
node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts
- Add
ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
to the KeyboardAvoidingView props.- 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; }
- 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.
I figured out the problem
It appears to be that at some point recently (pre iOS 17) a bug was introduced. Whenever
secureTextEntry={false}
andtextContentType
is set, various Text Input changes (typing, focus, etc...) will fire a nativekeyboardWillChangeFrame
event that causes the keyboard to re-render. This also causes iOS'sAutoFill QuickType Bar
(forgive me if my terminology is incorrect) to flicker.This can be especially problematic for any RN apps using
KeyboardAvoidingView
with iOSbehavior={'position'}
since it will cause a layout flicker as it adjusts to the disappearing and reappearingAutoFill QuickType Bar
.You can actually see the issue in native iOS apps:
- Go to the login screen of a native iOS app.
- Change focus from username and password fields.
- 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:
- Go to the file at:
node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
- Add
ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
to the KeyboardAvoidingView props.- Go to the types file at:
node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts
- Add
ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
to the KeyboardAvoidingView props.- 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; }
- 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...
@ThorANilsson solution worked for me. set textContentType='oneTimeCode' prop in textinput. Thanks
Has anyone found any solution for the keyboard to keep the password suggestion without flickering?
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
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...
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.
Is this problem exist in new major version 73.X, 74.X?
... textContentType='none' ...
not working on iOS 17+
I figured out the problem
It appears to be that at some point recently (pre iOS 17) a bug was introduced. Whenever
secureTextEntry={false}
andtextContentType
is set, various Text Input changes (typing, focus, etc...) will fire a nativekeyboardWillChangeFrame
event that causes the keyboard to re-render. This also causes iOS'sAutoFill QuickType Bar
(forgive me if my terminology is incorrect) to flicker.This can be especially problematic for any RN apps using
KeyboardAvoidingView
with iOSbehavior={'position'}
since it will cause a layout flicker as it adjusts to the disappearing and reappearingAutoFill QuickType Bar
.You can actually see the issue in native iOS apps:
- Go to the login screen of a native iOS app.
- Change focus from username and password fields.
- 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:
- Go to the file at:
node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
- Add
ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
to the KeyboardAvoidingView props.- Go to the types file at:
node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts
- Add
ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
to the KeyboardAvoidingView props.- 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; }
- 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…
Adding
textContentType='oneTimeCode'
to your TextInput disables the Password toolbar, which also eliminates the described issue.
Thanks @ThorANilsson
Btw with iOS 17.5 and expo SDK 51 I don't see this issue in my apps ( they are gone )
Adding
textContentType='oneTimeCode'
to your TextInput disables the Password toolbar, which also eliminates the described issue.
Thank you for saving my Day. <3
Thanks for textContentType='oneTimeCode'
I hope apple fixes this
https://github.com/facebook/react-native/assets/134932472/1dccf5fe-f3e5-42a0-a3cd-c6f28396b9bb
My main issue was a continuous state update on a screen that wasn't focused, causing the app to continuously rerender.
problem still exists. The textContentType="oneTimeCode" solves it, but removes the password autofill option.
I figured out the problem
It appears to be that at some point recently (pre iOS 17) a bug was introduced. Whenever
secureTextEntry={false}
andtextContentType
is set, various Text Input changes (typing, focus, etc...) will fire a nativekeyboardWillChangeFrame
event that causes the keyboard to re-render. This also causes iOS'sAutoFill QuickType Bar
(forgive me if my terminology is incorrect) to flicker.This can be especially problematic for any RN apps using
KeyboardAvoidingView
with iOSbehavior={'position'}
since it will cause a layout flicker as it adjusts to the disappearing and reappearingAutoFill QuickType Bar
.You can actually see the issue in native iOS apps:
- Go to the login screen of a native iOS app.
- Change focus from username and password fields.
- 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:
- Go to the file at:
node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
- Add
ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
to the KeyboardAvoidingView props.- Go to the types file at:
node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.d.ts
- Add
ignoreIOSKeyboardWillChangeEvents?: boolean | undefined;
to the KeyboardAvoidingView props.- 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; }
- 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 });
};
}
Try this simple solution :)
<TextInput
...
multiline
returnKeyType="done"
blurOnSubmit
/>
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!
Still no real solution. Disabling passwords autofill with textContentType="oneTimeCode"
, using multiline
, or overriding KeyBoardAvoidingView
is slop.
Still no real solution. Disabling passwords autofill with
textContentType="oneTimeCode"
, usingmultiline
, or overridingKeyBoardAvoidingView
is slop.
no one said this is a permanent fix, but its the only one that works with less code.
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