airbnb / native-navigation

Native navigation library for React Native applications
http://airbnb.io/native-navigation/
MIT License
3.13k stars 177 forks source link

how to push route without tab in tabs #134

Open taojoe opened 7 years ago

taojoe commented 7 years ago

I run the example code, all works great. I want the feature : the first screen is with tab, then push the 2nd screen, without tab showing, is this possible ? if possible how to do it ?

esam091 commented 7 years ago

I have no idea about Android. From iOS, it is supported from native code, using hidesBottomBarWhenPushed to the pushed view controller. To make it work when calling from JS however, you need to modify this method to be able to do what you want.

taojoe commented 7 years ago

@esam091 thanks. that can solve it. if this library can make it like navigation like instagram click the comment icon, it would be better.

i guess it maybe hard to do it, because native-navigation use one global navigation?

cesardeazevedo commented 7 years ago

I've been using the library the last days, and i am really enjoying it, but it seems that the tabs API isn't that ready, and pushing or presenting screens doesn't do anything with tabs, and the mode ('screen' | 'tabs') property is not there yet.

A better solution to work around this, and not change the library itself, would be to write a small native module to extend the native navigation to your needs.

I have a similar working case, a Login screen that doesn't has tabs and pushes to a Dashboard screen that has tabs, and the Dashboard screen has a List that each item pushes a 2nd screen without showing the tabs.

DashboardController.swift


import NativeNavigation

@objc(DashboardController)
class DashboardController : NSObject {
  fileprivate let coordinator: ReactNavigationCoordinator

  override init() {
    coordinator = ReactNavigationCoordinator.sharedInstance
  }

  @objc func presentScreenWithTabs() -> Void {
    DispatchQueue.main.async {
      let nav = self.coordinator.topNavigationController()
      let screen = ReactTabBarController(moduleName: "ScreenName")
      nav?.presentReactViewController(screen, animated: true, completion: nil)
    }
  }

  @objc func pushScreenWithoutTabs(_ props: [String: AnyObject]) -> Void {
    DispatchQueue.main.async {
      let nav = self.coordinator.topNavigationController()
      let screen = ReactViewController(moduleName: "ScreenName", props: props)
      screen.hidesBottomBarWhenPushed = true
      nav?.pushViewController(screen, animated: true)
    }
  }
}

Link the functions with the bridge.

DashboardBridge.m


#import "React/RCTBridgeModule.h"

@interface RCT_EXTERN_MODULE(DashboardController, NSObject)

RCT_EXTERN_METHOD(presentScreenWithTabs)
RCT_EXTERN_METHOD(pushScreenWithoutTabs:(NSDictionary *) props)

@end

Then invoke it as follows


import { NativeModules } from 'react-native'

handlePress() {
  NativeModules.DashboardController.pushScreenWithoutTabs()
}

Note that this isn't actually the best solution, but just a way to extend the native-navigation to our needs, until we don't have a full tabs API, which may take some time.

I will try to update my answer for android when i get there.

notjosh commented 7 years ago

fwiw, I've implemented this over on our fork: https://github.com/taxfix/native-navigation/pull/9 (amongst some other things, ymmv)