IjzerenHein / react-navigation-shared-element

React Navigation bindings for react-native-shared-element 💫
https://github.com/IjzerenHein/react-native-shared-element
MIT License
1.27k stars 124 forks source link

Problem with SharedElement animation while trying to navigate between different tabs in BottomTabNavigator #152

Open tmrovsky opened 3 years ago

tmrovsky commented 3 years ago
"@react-navigation/bottom-tabs": "5.11.2",
"@react-navigation/native": "~5.8.10",
"@react-navigation/stack": "~5.12.8",
"expo": "~40.0.0",
"react-native-gesture-handler": "~1.8.0",
"react-native-reanimated": "^2.0.0",
"react-native-screens": "~2.15.0",
"react-native-shared-element": "^0.7.0",
"react-navigation-shared-element": "^3.0.0"

Hey! 👋

I have a problem while trying to navigate from AccountComponent to InformationComponent (from AccountStack to InformationStack). I would like to see working animation on the SharedElement which is rendered under two different BottomTab.Screen. I've tried to look into examples to find the solution and I found that example. Unfortunately it's not working for me. Animation works only if two components(screens) are part of the same stack in BottomTabNavigator. Unfortunately, I need them in two different stacks and in that case, the animation does not work. Hope someone will be able to help me.

Code sample below ⬇️

import { Ionicons } from '@expo/vector-icons'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import * as React from 'react'
import { Pressable, Text, View } from 'react-native'
import { createSharedElementStackNavigator, SharedElement } from 'react-navigation-shared-element'

import { Colors } from '@constants/Colors'
import { useColorScheme } from '@hooks/useColorScheme'

import { RouteParamsMap } from '../RouteParamsMap'
import { Routes } from '../types'

type BottomTabRoutes =
  | Routes.AccountStack
  | Routes.InformationStack
  | Routes.HistoryStack
  | Routes.RaiseIssueStack
type BottomTabParamsMap = Pick<RouteParamsMap, BottomTabRoutes>

const BottomTab = createBottomTabNavigator<BottomTabParamsMap>()

//TODO: Create RaiseIssueStack, AccountStack, InformationStack, HistoryStack and delete those temporary components
const RaiseComponent = () => {
  return (
    <View>
      <Text>RAISE</Text>
    </View>
  )
}

const AccountComponent = props => {
  return (
    <View
      style={{
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
      }}
    >
      <SharedElement id="sharedId">
        <Pressable onPress={() => props.navigation.navigate(Routes.InformationStack)}>
          <Text>Account</Text>
        </Pressable>
      </SharedElement>
    </View>
  )
}

const InformationComponent = props => {
  return (
    <View
      style={{
        flex: 1,
        alignItems: 'flex-start',
        justifyContent: 'flex-start',
      }}
    >
      <SharedElement id="sharedId">
        <Pressable onPress={() => props.navigation.goBack()}>
          <Text>INFORMATION</Text>
        </Pressable>
      </SharedElement>
    </View>
  )
}

const HistoryComponent = () => {
  return (
    <View>
      <Text>HISTORY</Text>
    </View>
  )
}

AccountComponent.sharedElements = route => {
  return [
    {
      id: `sharedId`,
      animation: 'fade',
      resize: 'clip',
      align: 'left-top',
    },
  ]
}

InformationComponent.sharedElements = route => {
  return [
    {
      id: `sharedId`,
      animation: 'fade',
      resize: 'clip',
      align: 'left-top',
    },
  ]
}

const Stack = createSharedElementStackNavigator()
const Stack2 = createSharedElementStackNavigator()

const AccountStack = () => (
  <Stack.Navigator>
    <Stack.Screen name="Account" component={AccountComponent} />
    {/* <Stack.Screen name="Information" component={InformationComponent} /> */}
  </Stack.Navigator>
)

const InformationStack = () => (
  <Stack2.Navigator>
    {/* <Stack2.Screen name="Account" component={AccountComponent} /> */}
    <Stack2.Screen name="Information" component={InformationComponent} />
  </Stack2.Navigator>
)

export function BottomTabNavigator() {
  const colorScheme = useColorScheme()

  return (
    <BottomTab.Navigator
      initialRouteName={Routes.RaiseIssueStack}
      tabBarOptions={{ activeTintColor: Colors[colorScheme].tint }}
    >
      <BottomTab.Screen
        name={Routes.AccountStack}
        component={AccountStack}
        options={{
          tabBarIcon: ({ color }) => <TabBarIcon name="ios-code" color={color} />,
        }}
      />
      <BottomTab.Screen
        name={Routes.InformationStack}
        component={InformationStack}
        options={{
          tabBarIcon: ({ color }) => <TabBarIcon name="ios-code" color={color} />,
        }}
      />
      <BottomTab.Screen
        name={Routes.HistoryStack}
        component={HistoryComponent}
        options={{
          tabBarIcon: ({ color }) => <TabBarIcon name="ios-code" color={color} />,
        }}
      />
      <BottomTab.Screen
        name={Routes.RaiseIssueStack}
        component={RaiseComponent}
        options={{
          tabBarIcon: ({ color }) => <TabBarIcon name="ios-code" color={color} />,
        }}
      />
    </BottomTab.Navigator>
  )
}

// You can explore the built-in icon families and icons on the web at:
// https://icons.expo.fyi/
function TabBarIcon(props: { name: React.ComponentProps<typeof Ionicons>['name']; color: string }) {
  return <Ionicons size={30} style={{ marginBottom: -3 }} {...props} />
}
vivianmauer commented 3 years ago

I have the same problem, did you find a solution?

WhoISTheGuy commented 2 years ago

HELP same problem

WhoISTheGuy commented 2 years ago

HELP same problem

Found a solution.

https://github.com/IjzerenHein/react-navigation-shared-element/blob/main/example/src/tests/BottomTabs2.tsx