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

Screen transition animation flickers when calling .focus() on a TextInput while the transition is in progress #1061

Closed
SimpleCreations opened this issue Aug 18, 2021 · 6 comments

Comments

@SimpleCreations
Copy link

Description

Demo:

Simulator.Screen.Recording.-.iPhone.11.Pro.-.2021-08-19.at.01.15.09.mp4

Steps To Reproduce

  1. Have a TextInput inside a screen.
  2. Navigate to the screen.
  3. Focus the TextInput some time after the screen mount, but before the screen transition animation ends. In the example I use setTimeout to call the .focus() method with a 10ms delay.

I think I should note that there's no flickering when using autoFocus prop or when focusing the TextInput on mount without a delay. The reason I use setTimeout to begin with is because otherwise I have layout issues due to a workaround I implemented for #649.

Expected behavior

The transition animation is smooth.

Actual behavior

There is flickering during the transition animation.

Snack or minimal code example

import React, { useEffect, useRef } from "react";
import { Button, SafeAreaView, TextInput } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator, NativeStackScreenProps } from "react-native-screens/native-stack";

const RootStack = createNativeStackNavigator();

type RootStackParamsList = {
  FirstScreen: undefined;
  SecondScreen: undefined;
};

const FirstScreen = ({navigation}: NativeStackScreenProps<RootStackParamsList>) => (
  <SafeAreaView>
    <Button
      title="Navigate to SecondScreen"
      onPress={() => navigation.navigate("SecondScreen")} />
  </SafeAreaView>
);

const SecondScreen = () => {

  const textInputRef = useRef<TextInput>(null);
  useEffect(() => {
    const timeout = setTimeout(() => {
      textInputRef.current!.focus();
    }, 10);
    return () => clearTimeout(timeout);
  });

  return (
    <SafeAreaView>
      <TextInput
        style={{margin: 16, borderWidth: 1}}
        ref={textInputRef} />
    </SafeAreaView>
  );

};

const App = () => (
  <NavigationContainer>
    <RootStack.Navigator
      initialRouteName="FirstScreen">
      <RootStack.Screen
        name="FirstScreen"
        component={FirstScreen} />
      <RootStack.Screen
        name="SecondScreen"
        component={SecondScreen} />
    </RootStack.Navigator>
  </NavigationContainer>
);

export default App;

Package versions

  • React: 17.0.1
  • React Native: 0.64.1
  • React Native Screens: 3.5.0
@Razorholt
Copy link

You may use the autofocus prop in TextInput or wait until the transition is over and the page is in focus

    useEffect(() => {
        const pageFocused= navigation.addListener("focus", () => {
              const timeout = setTimeout(() => {
                textInputRef.current!.focus();
              }, 100);
        });
        return pageFocused;
    }, [navigation]);

@SimpleCreations
Copy link
Author

@Razorholt hi! I think I mentioned in the issue that everything is fine when using autoFocus; the reason I tried a small timeout was a hacky workaround for one of the other bugs. (And although setting a long timeout works and doesn't trigger the flickering, it leads to bad UX.)
Nevertheless, I thought the issue was worth reporting regardless of how and why the TextInput is focused during the transition, because it seems react-native-screens doesn't respond to that properly.

@Razorholt
Copy link

@Razorholt hi! I think I mentioned in the issue that everything is fine when using autoFocus; the reason I tried a small timeout was a hacky workaround for one of the other bugs. (And although setting a long timeout works and doesn't trigger the flickering, it leads to bad UX.)
Nevertheless, I thought the issue was worth reporting regardless of how and why the TextInput is focused during the transition, because it seems react-native-screens doesn't respond to that properly.

Sorry, my bad.

@WoLewicki
Copy link
Member

I tested such behavior on clean native iOS project by adding focusing block during the transition of VCs and the flicker happens there too. It looks like the behavior of UIKit then and I am afraid we cannot do anything about it in react-native-screens. Can I help you more with this?
Simulator Screen Recording - iPhone SE (2nd generation) - 2021-09-15 at 11 10 43

@SimpleCreations
Copy link
Author

SimpleCreations commented Sep 15, 2021

@WoLewicki Thank you for taking a look at it!
That's unfortunate. If it's a native iOS issue I guess nothing else can be done.

@WoLewicki
Copy link
Member

I guess that focusing during the transition is something that should not be done anyways. I will close this issue then. Feel free to comment if I am wrong at something and we can reopen it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants