Closed ACOSW closed 6 years ago
This problem happens because the second screen is mounted before the push-animation finished. All native events (include keyboards) are share between Screens.
This issue could be solved by using fade animation or delay the TextInput from rendering too soon.
@pqkluan is there a way to have a text input autofocused and the keyboard skip animation on a new screen without a fade in or flickering?
For example, many apps have this such as Facebook messenger and others (when you select a chat, input is focused and keyboard is up on new screen before transition.
We also have this issue, it's pretty annoying that we have to delay input focusing
This needs to be fixed
Same. Adding a timeout seems to be the only fix for now.
I'm also having this issue.
No better solution besides timeout? Will be awesome if RNN itself fix this problem, because everyone could face this glitch. Also in modals use of autoFocus makes view empty for duration of appear animation. This adds annoying delays before screen body actually showed.
The way I'm getting around it is to remove the autoFocus
from the input and instead add a ref to the input, setup an event listener and focus when the screen appears:
class MyComponent extends Component {
componentDidMount() {
this.navigationEventListener = Navigation.events().bindComponent(this)
}
componentWillUnmount() {
// Not mandatory
if (this.navigationEventListener) {
this.navigationEventListener.remove()
}
}
componentDidAppear() {
if (this.input) this.input.focus()
}
render() {
return (
<Input ref={ref => this.input = ref} />
)
}
}
componentDidMount() { this.navigationEventListener = Navigation.events().bindComponent(this) }
componentWillUnmount() { // Not mandatory if (this.navigationEventListener) { this.navigationEventListener.remove() } }
componentDidAppear() { if (this.input) this.input.focus() }
It's not working for me.
@ATShiTou how are you creating your ref?
I had resolved my problem. Mine is showOverlay
problem, not push
. Thank you anyway.
@chrise86 's solution is the best for now but this is still happening for us.
Why is this closed? It's still an issue in 3.2.0
I have slightly different behavior in my app: when I push a screen with an autofocused input, the screen animates without the keyboard, then jumps back 1/4 of the screen, but now with the keyboard visible, and completes the push animation again. So it kind of jerks back and forth.
Try to set animations: {push:{waitForRender: true}}
in static options=...
for screen where you have autofocus input
I fixed that by
componentDidMount() {
this.navigationEventListener = Navigation.events().bindComponent(this);
}
componentWillUnmount() {
// Not mandatory
if (this.navigationEventListener) {
this.navigationEventListener.remove();
}
}
componentDidAppear() {
this.input.focus();
}
render(){
return <input ref={node => (this.input = node)} />
}
@soroush-b that’s the solution I posted above. For those saying it’s still an issue, I’m not sure there is anything that can be done to “fix it” other than solutions like this. As @pqkluan said early on, it’s due to the component mounting before the native animation is complete.
Try to set
animations: {push:{waitForRender: true}}
instatic options=...
for screen where you have autofocus input
Your solution works in RNN v2.27.9, thanks!
waitForRender removed the animation entirely. As in with that configuration autofocus
just stopped working. Had to use the setTimeout
approach.
Still an issue in the latest versions.
The current approach that I use:
If your app is using a custom InputField:
import {useNavigationComponentDidAppear} from 'react-native-navigation-hooks';
const CustomInputField = ({shouldAutoFocus}) => {
const inputRef = useRef(null);
useNavigationComponentDidAppear(() => {
if (shouldAutoFocus) {
inputRef.current && inputRef.current.focus();
}
});
return (
<TextInput
ref={inputRef}
{...restProps}
/>
)
}
And wherever you use CustomInputField: <CustomInputField shouldAutoFocus />
Old thread, I’m aware, but I thought leaving this here might help people who use functional components:
import {useNavigationComponentDidAppear} from 'react-native-navigation-hooks';
…
/**
* Focus input once screen has appeared for the first time
*/
const inputRef = useRef(null);
const shouldAutoFocus = useRef(true);
useNavigationComponentDidAppear(() => {
if (shouldAutoFocus.current) {
inputRef.current?.focus();
shouldAutoFocus.current = false;
}
}, componentId);
…
<TextInput
ref={inputRef}
…
/>
You can use it. It's work for me!
Be sure add these imports:
import React, {useState, useRef, useEffect} from 'react';
Add useState
const [searchValue, setSearchValue] = useState("");
Add useRef
const inputSearch = useRef<TextInput>(null);
Add useEffect
useEffect(() => { setTimeout(() => { inputSearch.current && inputSearch.current.focus(); }, 450); }, [])
(450 milliseconds because... The default animation duration for screen transitions in React Native Navigation libraries like React Navigation is typically around 300 milliseconds.)
For input
<TextInput onChangeText={(e) => setSearchValue(e)} value={searchValue} placeholder='Search' ref={inputSearch} />
Now animations will be on time and the keyboard will appear without twitching.
Or do it for <Stack.Navigator screenOptions={{ animation: 'none' }}>
Or
<Stack.Screen name="Search" component={SearchScreen} options={{ headerShown: false, gestureDirection: "vertical" }} />
without useEffect and without useRef
And add this:
autoFocus={true}
Still an issue with latest versions if we want to avoid using a timeout
Issue Description
Keyboard flicks while pushing screen with autofocus TextInput. Flickering appears only with default ios animation (horizontal-slide), with "fade" animation keyboard appears fine.
Steps to Reproduce / Code Snippets / Screenshots
Simply push to the navigation stack new screen with autofocus input and you'll see same keyboard flickering as on attached gif image:
Environment