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

[iOS] Navigation from drawer doesn't work #1143

Closed
terrysahaidak opened this issue Apr 26, 2017 · 24 comments
Closed

[iOS] Navigation from drawer doesn't work #1143

terrysahaidak opened this issue Apr 26, 2017 · 24 comments

Comments

@terrysahaidak
Copy link

terrysahaidak commented Apr 26, 2017

Issue Description

Pushing navigator from drawer does nothing.
This behavior exists only in iOS. The Same code works as well in Android.
When I use navigation ref from the other screen, everything works well.

Here is an example: https://github.com/terrysahaidak/GitterMobile/blob/tr-react-native-navigation/app/screens/Drawer/index.js#L35-L40

Steps to Reproduce / Code Snippets / Screenshots

Setup Root screen with navigation.
Push from 'drawer' with this.props.navigator.push({})


Environment

  • React Native Navigation version: 1.1.24
  • React Native version: 0.43.3
  • Platform(s) (iOS, Android, or both?): iOS only
  • Device info (Simulator/Device? OS version? Debug/Release?): Simulator. macOS Sierra 10.12.3. Debug
@thomaschauffour
Copy link

thomaschauffour commented Apr 26, 2017

+1 Same issue

@jtibbertsma
Copy link
Contributor

I always thought that this was expected behavior. I've been pushing screens from the drawer by issuing redux actions that cause the navigator on the main screen to do the push.

@grigored
Copy link

How do you access the main screen navigator in redux?

@jtibbertsma
Copy link
Contributor

It's feels a little bit hacky but I'm using a custom redux middleware. The middleware file exports a function that you can use to set the global navigator object. The middleware itself listens for specific redux actions (like NAVIGATION_PUSH etc) and when it sees one, it sends the action payload to the appropriate method on the navigator. There's also a higher order component called rootScreen that I decorate each of my root screen with. The higher order component uses its constructor to register props.navigator with the redux middleware.

The thing I like about doing it this way is that if you want, you can keep track of your navigation stack in your redux store, and do things like throttle pushes so that it doesn't push the same screen twice if the press a button twice super fast.

@thomaschauffour
Copy link

I do not currently use Redux in my application. So how do we do that?

@terrysahaidak
Copy link
Author

terrysahaidak commented Apr 27, 2017

@DemisBand, currently, as a workaround, you can export navigator reference from your root screen. You need to define variable and export it:

export let rootNavigator = null

Then you need to assign navigator ref to it on your RootScreen constructor:

class RootScreen extends Component {
  constructor() {
    rootNavigator = this.props.navigator
  }
  // ..some other code
}

And then you can use it in the whole app after RootScreen initialized:

import {rootNavigator} from './RootScreen'

class Drawer extends Component {
  handleNavigate() {
    this.props.navigator.push({screen: 'SomeScreen'}) // won't work
    rootNavigator.push({screen: 'SomeScreen'}) // works as well
  }
}

Or you can also wrap each screen with HOC and pass navigation prop to it from somewhere and pass to your screens.

@thomaschauffour
Copy link

@terrysahaidak Thanks, it's work 👍

@srishanbhattarai
Copy link

srishanbhattarai commented May 10, 2017

Sorry to reopen this issue.

@terrysahaidak - Your solution pushes a new screen at the level of the root navigator. I want a new screen to be pushed on top of only the drawer, not the primary screen on the stack from which I'm using the navigator. I believe this is the expected behaviour for your workaround, but if I wanted to push a screen on top of only the drawer, how would I go about doing that?

UPDATE: It seems the .toggleDrawer function does not pass all of the navigation props to the drawer view like it does with a .push Why is this the case? How can I work around this?

Thanks.

@terrysahaidak
Copy link
Author

@srishanbhattarai, I think your use case is not supported yet.

But as a workaround, you can use legacy (or any other js implementation) navigator inside your drawer view. I think it should work.

@srishanbhattarai
Copy link

@terrysahaidak
Well that's too bad. Thanks anyway.

@Kabangi
Copy link

Kabangi commented May 22, 2017

Am experiencing this issue on my project, I have applied the workaround given by @terrysahaidak which works great but I can't seem to trigger this.props.navigator.toggleDrawer({}) I have also tried rootNavigator.toggleDrawer still doesn't work;

Any workaround for this?

@PARAGJYOTI
Copy link

PARAGJYOTI commented May 25, 2017

@terrysahaidak Thank you so much ..

@ghost
Copy link

ghost commented Jun 29, 2017

@terrysahaidak I've tried your work around but it's not working. I'm first using StartSingleScreenApp for the auth flow and then I use startTabBasedApp for my main app. When I import the rootNavigator from my sideMenu and try to make a push({}) it isn't doing anything. If I console.log(rootNavigator) I can see it. btw my Drawer is attached to my tabbasedapp.

@terrysahaidak
Copy link
Author

@DEEvent you can also try to use Deep links as an alternative to navigator.push.

@typhoon2099
Copy link

typhoon2099 commented Jun 30, 2017

Is this still an issue? I have a drawer in my app and I've had to add a ton of code to explicitly get the drawer to work on iOS. On Android the only code I needed to open the drawer was:
leftButtons: [ { id: 'sideMenu', }, ],

This doesn't work on iOS so i had to explicitly define the icon before it would show. Now I have the drawer opening but this.props.navigator doesn't seem to work properly. I also had to add a setOnNavigatorEvent() handler to open the drawer using the icon (again something that was not required for Android). In the Drawer component then toggleDrawer() will close the drawer but push() and popToRoot() do not work.

XCode's logs show this.props.navigator with the following properties:

{ navigatorID: 'controllerID3_drawer', screenInstanceID: undefined, navigatorInstanceID: undefined, navigatorEventHandler: null, navigatorEventSubscription: null }

on Android I get:

{ navigatorID: 'navigatorID5_nav', screenInstanceID: 'screenInstanceID6', navigatorInstanceID: 'screenInstanceID6_events', navigatorEventHandler: null, navigatorEventSubscription: null }

@ghost
Copy link

ghost commented Jun 30, 2017

@terrysahaidak Thanks ! Deep links did the trick for me.

@ODelibalta
Copy link

@DEEvent thank you for your deep link mention. It helped me alot. @jtibbertsma PLEASE make an example repo. What you described sounds great and I hope it is for a tab based app.

I've tried all solutions here. While I got it to navigate, it is buggy. I am using a tab based app. If I want my drawer link to navigate from any of the tab screens, I have to add the deep link listener to all tab screens, which I understand, but then the same screen gets pushed to all my tabs.

I ended up adding a switch to tab method first that goes to my first tab screen (home) and use that as my "root" screen so the deep link listener first switches to my home tab screen then pushes the drawer screen on top. However, :) if I navigate away from home to another tab and come back to home tab, I see the pushed screen and not the home tab.

@jtibbertsma
Copy link
Contributor

@thadeu
Copy link

thadeu commented Dec 6, 2017

@terrysahaidak @DemisBand I had same error here, solved with your help as well!

@mrlaunch
Copy link

mrlaunch commented Feb 16, 2018

I am using drawer with tab bar at the bottom.
So I started app using Navigation.startTabBasedApp and has 5 tabs.
@terrysahaidak can you please let me know on which scene file should I export rootNavigator or handle deep link?
@ODelibalta do you have solution for your issue?

@stale
Copy link

stale bot commented Jun 2, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you believe the issue is still relevant, please test on the latest version and report back. Thank you for your contributions.

@stale stale bot added the 🏚 stale label Jun 2, 2018
@guyca guyca removed the Bug - iOS label Jun 4, 2018
@stale stale bot removed the 🏚 stale label Jun 4, 2018
@ispadoto
Copy link

I'm seeing this issue here...
I have a drawer that call a push from a deepLink...
this.props.navigator is there (_proto has a push() method) but when exec, the message appears...

@stale
Copy link

stale bot commented Aug 3, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you believe the issue is still relevant, please test on the latest version and report back. Thank you for your contributions.

@stale stale bot added the 🏚 stale label Aug 3, 2018
@stale
Copy link

stale bot commented Aug 10, 2018

The issue has been closed for inactivity.

@stale stale bot closed this as completed Aug 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests