Search code examples
react-nativereact-navigationreact-navigation-stack

Title animations on screen transition in custom Header component?


I have my own Header component that has a search field and some other features unique to my app. I simply define it on the navigationOptions for each screen.

SomeScreen.navigationOptions = (props) => ({
  header: <Header {... props} />,
});

What I want to do though is animate the title inside the component itself as it moves from screen to screen? In general how can I accomplish this with a custom header? I've looked at the react-navigation-stacks implementation of Header but I can't make much sense of it.


Solution

  • Depending on your version of stack navigator, you'll need to check the props you receive. First of all, pass a function returning an element to the header option so that you receive the props:

    SomeScreen.navigationOptions = {
      header: props => <Header {...props} />
    };
    

    If you're on react-navigation-stack@2.x (alpha), you get a prop called scene. It's an object containing a progress property which has 3 properties which are reanimated nodes.

    • current: represents the progress of the screen that the header, it ranges from 0 to 1, where 0 means the screen is fully hidden, and 1 means the screen is fully shown.
    • next: similar to current, but for the next screen in the stack. can be undefined when there's no next screen
    • previous: similar to current, but for the previous screen in the stack. can be undefined when there's no previous screen

    You can interpolate on these values to animate your view. For example, say you want to animate the opacity to start from 0.5 and to 1 as screen comes in:

    import Animated from "react-native-reanimated";
    
    // ...
    
    <Animated.Text
      style={{
        opacity: Animated.interpolate(scene.progress.current, {
          inputRange: [0, 1],
          outputRange: [0.5, 1]
        })
      }}
    />;
    

    If you're on react-navigation-stack@1.x, you get a prop called position. It's an animated node which represents the current position of the stack (ranges from 0 to current index). You can interpolate on it to animate your header. It can be a bit tricky, so you'll have to play around.

    For example, say you want to animate the opacity to start from 0.5 and to 1 as screen comes in:

    NOTE: I haven't tested this one so the code might be wrong. So you'll have to play around with it.

    import { Animated } from "react-native";
    
    // ...
    
    <Animated.Text
      style={{
        opacity: position.interpolate({
          inputRange: [index - 1, index],
          outputRange: [0.5, 1]
        })
      }}
    />;