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

Is a shared transition between a screen with a bottomTabNavigator and another without possible? #42

Closed
vitosorriso opened this issue Mar 24, 2020 · 11 comments

Comments

@vitosorriso
Copy link

Hello everyone. I want to implement a shared transition like the infamous App of the day iOS transition between a screen which should have the bottomTabNavigator (the list) and another screen which should't have the tab (the detail). Is it possible?

I usually do tricks with bottomTabNavigator using a navigation param and playing with tabBarVisible option navigationOptions into createBottomTabNavigator; logic seems good, however the transition when I go back it's buggy, because the animation of placing back the image in its original place acts like there is no tabBar and it's buggy.

It looks like the tabBar is adding some kind of offset to the animation.
(animation works like a charm on both android/ios if i leave the tabBar always visible)

packages:
"react": "16.9.0",
"react-native": "0.61.5",
"react-native-shared-element": "^0.5.6",
"react-navigation": "^4.1.0",
"react-navigation-shared-element": "^2.2.0",
"react-navigation-stack": "^2.1.0",
"react-navigation-tabs": "^2.7.0"

the code about navigation:

import { createAppContainer, createSwitchNavigator } from 'react-navigation'
import { createBottomTabNavigator } from 'react-navigation-tabs'
import { createStackNavigator } from 'react-navigation-stack'
// other imports here
import Second from './views/Second'
import ExampleDetail from './views/ExampleDetail'

// other navigation stacks here
const FakeNavigator = createSharedElementStackNavigator(
  { Second, ExampleDetail },
  { headerMode: 'none', mode: 'modal' },
)

const Tabs = createBottomTabNavigator(
  {
    Discover: {
      screen: Discover,
      navigationOptions: {
        tabBarIcon: ({ tintColor }) => <IconSimpleLine name="notebook" style={{ fontSize: 24, color: tintColor }} />,
      },
    },
    Second: {
      screen: FakeNavigator,
      navigationOptions: ({ navigation }) => ({
        tabBarIcon: ({ tintColor }) => <IconSimpleLine name="handbag" style={{ fontSize: 24, color: tintColor }} />,
        // here i check the navigation param to let the tabBar be visible or not
        tabBarVisible: !navigation.state?.routes[navigation.state.index].params?.hideTabBar,
      }),
    },
    // other tabs here..
  },
  {
    tabBarOptions: {
      showLabel: false,
      activeTintColor: 'black',
      inactiveTintColor: 'gray',
    },
  },
)


const AppStackNavigator = createStackNavigator(
  { Tabs, RaffleDetail, DiscoverDetail, FakeNavigator },
  { headerMode: 'none' },
)

const AppNavigator = createSwitchNavigator(
  {
    auth: AuthNavigator,
    app: AppStackNavigator,
  },
  { initialRouteName: 'auth' },
)

const AppContainer = createAppContainer(AppNavigator)

the code responsible to open the detail page:

  const onPress = () => {
    navigation.navigate('ExampleDetail', { detail: { title, subtitle, picture, id }, hideTabBar: true })
  }

from the detail page i simply call navigation.goBack()

this is the result (gif looks slow but the opening animation works like a charm):

Screen-Recording-2020-03-24-at-1

Where is the mistake? Is this behaviour possible or not? Thanks in advance.

@phamhoaivu911
Copy link
Contributor

phamhoaivu911 commented Mar 26, 2020

Hi @IjzerenHein, first thank you for your awesome library.

I have the same issue with @vitosorriso, but on Android. When I go back from a screen that hides the bottom tab navigator, it seems that the bottom tab affects the size of the original image and its position.

This is the gif image of the issue

This is the repository to reproduce the issue: https://github.com/phamhoaivu911/RNSE_example

Any help would be much appreciated. Please let me know if there's anything I can do to help. Thank you!

@vitosorriso
Copy link
Author

Hello @phamhoaivu911 , actually i think you run into another "issue". If you scroll on the list before the animation ends, you run in this issue. I saw your code, you use useNavigation() hook. I am using the navigation prop, I just add a didFocus listener and my ScrollView is disabled until the didFocus event happens!
Code inside my list component (called Second)

  useEffect(() => {
    // if the tabBar is already visible, animation will flicker
    // because tabBar adds offset to animation!
    // didFocus is called right after the transition ends!
    setScrollEnabled(true)
    const onFocus = (): void => {
      navigation.setParams({ hideTabBar: false })
      setScrollEnabled(true)
    }

    const focusListener = navigation.addListener('didFocus', onFocus)

    return (): void => focusListener.remove()
  }, [])

this is also how I tried to solve my issue! And actually works but I think i need to create a custom Animated BottomTabBar.

Like this, I make the tabBar show only when the animation ends. Also, I disable the scroll until this event occurs.

// code to go into detail

  const onPress = useCallback(
    ({ title, subtitle, picture, id }: SharedCardContentType) => (): void => {
      setScrollEnabled(false)
      navigation.navigate('ExampleDetail', { detail: { title, subtitle, picture, id }, hideTabBar: true })
    },
    [],
  )

// code into detail (I do the same trick into detail)

  useEffect(() => {
    const onFocus = (): void => setScrollEnabled(true)
    const focusListener = navigation.addListener('didFocus', onFocus)

    return (): void => focusListener.remove()
  }, [])

// code into navigation to show/hide tabbar (createBottomTabNavigator(

    Second: {
      screen: FakeNavigator,
      navigationOptions: ({ navigation }) => ({
        tabBarIcon: ({ tintColor }) => <IconSimpleLine name="handbag" style={{ fontSize: 24, color: tintColor }} />,
        tabBarVisible: !navigation.state?.routes[navigation.state.index].params?.hideTabBar,
      }),
    },

I'm using react-navigation 4

@phamhoaivu911
Copy link
Contributor

phamhoaivu911 commented Mar 28, 2020

Hi @vitosorriso , I'm using react-navigation v5 and my issue only happens on Android. It seems that my problem only happens with react-navigation v5 because the Example from the author works well with react-navigation v4.

My issue is that the bottom tab affects the animation when going back. It may add some offsets
or affect the visual content of the original element. I'm still investigating it.

Showing the bottom tab after the animation is complete is a possible workaround. Since the animation works fine without the bottom tab, we can wait for it to complete, then show the bottom tab on the front. But I want to fix the root cause instead of this workaround.

Moreover, setParams works similar to setState, which makes the navigator re-render. As a result, we don't have a smooth animation as we expected.

@IjzerenHein
Copy link
Owner

Hi! I've updated the app in ./example so we can add tests and examples in there. Could you add a test-case to the ./example app showcasing this problem?

@phamhoaivu911
Copy link
Contributor

Hi @IjzerenHein . I created a PR #58 . Please take a look. I'm also going to create another issue for v5 so we can keep track of it.
Thank you!

@IjzerenHein
Copy link
Owner

Awesome, thanks for the PR!

@phamhoaivu911
Copy link
Contributor

phamhoaivu911 commented Apr 14, 2020

Hi @IjzerenHein , according to this doc, we were hiding the bottom tab the wrong way, which leads to the glitch, so I created another PR to correct it. But it seems that we have another issue. Please take a look and let me know if there's anything I can help with.

Thank you!

@IjzerenHein
Copy link
Owner

@phamhoaivu911 I'm still in the process of working through the issues and v5 compatibility. But, I did find a possible workaround for this. When you wrap your screen that is inside the bottom-navigator with a SharedElementStack, then it should successfully pick the transitions. I've updated the BottomTabs2 example to demonstrate this workaround:
https://github.com/IjzerenHein/react-navigation-shared-element/blob/master/example/src/tests/BottomTabs2.v4.tsx

@phamhoaivu911
Copy link
Contributor

Thanks @IjzerenHein so much for your hard work 🎉 !

Looking for v5 to be released.

@dochonglo
Copy link

Hi @IjzerenHein !! Thanks for the wonderful library and the example project. 😊

I'm interested to know how you were able to hide the tab bar under the example "BottomTabs2" for react navigation v4 and v5. I've been playing around with the demo and searching through the files, but I found no clues as to how the tab bar transitioned to hidden when navigating to the detailed screen.

I'd much appreciate your help. Thanks in advance and keep up the excellent work!

@IjzerenHein
Copy link
Owner

@ismaelbarry please view the answer here: #188 (comment)

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

4 participants