Tabs Setup (iOS)

The Navigation router for React Native uses the underlying native APIs to provide faithful navigation on Android and iOS. Because it contains native code you first have to eject from create-react-native-app or create your application using react-native init.

Note

If you don't want a tabbed interface in iOS then follow the Setup instructions instead

Install the three navigation packages from npm.

npm install navigation navigation-react navigation-react-native --save

Link the navigation-react-native package.

react-native link navigation-react-native

JavaScript

Replace the code in App.js with that shown below. This setup is for 2 tabs. For each extra tab you require add an extra new StateNavigator(stateNavigator) to the stateNavigators array.

import React from 'react';
import {StateNavigator} from 'navigation';
import {NavigationHandler} from 'navigation-react';
import {addNavigateHandlers, Scene} from 'navigation-react-native';

var stateNavigator = new StateNavigator([
]);

var stateNavigators = [stateNavigator, new StateNavigator(stateNavigator)];

addNavigateHandlers(stateNavigators);

export default ({crumb, tab = 0}) => (
  <NavigationHandler stateNavigator={stateNavigators[tab]}>
    <Scene crumb={crumb} />
  </NavigationHandler>
);

Android

Locate the AndroidManifest.xml in the Android project and add a launchMode of singleTop to the MainActivity.

<activity
  android:name=".MainActivity"
  android:launchMode="singleTop"
  ...

iOS

Locate the AppDelegate.h in the iOS project and replace the code with the following:

#import <UIKit/UIKit.h>
#import <React/RCTBridge.h>
#import "NVApplicationHostDelegate.h"

@interface AppDelegate : UIResponder <NVApplicationHostDelegate>

@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, strong) RCTBridge *bridge;

@end

Locate the AppDelegate.m in the iOS project and replace the code with that shown below. Change the "Tab1" and "Tab2" placeholder strings to the names of your tabs. Change the "appKey" placeholder string to the name of your application (it should match the key used in the registerComponent call in index.js). This setup is for 2 tabs. For each extra tab you require add an extra item to the tabs array.

#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "NVSceneController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
  
  self.bridge = [[RCTBridge alloc] initWithBundleURL:jsCodeLocation moduleProvider:nil launchOptions:launchOptions];  
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

  NSArray *tabs = @[@"Tab1", @"Tab2"];
  NSString *appKey = @"appKey";

  NSMutableArray *controllers = [[NSMutableArray alloc] init];
  for(NSInteger tab = 0; tab < [tabs count]; tab++) {
    UIViewController *sceneController = [[NVSceneController alloc] init:0 tab:tab title:tabs[tab] appKey:appKey];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:sceneController];
    navigationController.tabBarItem = [[UITabBarItem alloc] initWithTitle:tabs[tab] image:nil tag:tab];
    [controllers addObject:navigationController];
  }

  UITabBarController *tabBarController = [[UITabBarController alloc] init];
  [tabBarController setViewControllers:controllers];
  self.window.rootViewController = tabBarController;
  [self.window makeKeyAndVisible];
  return YES;
}

@end