|  | @@ -1,10 +1,32 @@
 | 
	
		
			
			| 1 | 1 |  # React Native Navigation
 | 
	
		
			
			| 2 | 2 |  
 | 
	
		
			
			| 3 |  | -### `Navigation`
 | 
	
		
			
			|  | 3 | +App-wide support for 100% native navigation with potential isolation support. For iOS, this package is a wrapper around [react-native-controllers](https://github.com/wix/react-native-controllers) which provides a simplified more abstract API. This abstract API will be unified with the Android solution which is still work in progress.
 | 
	
		
			
			| 4 | 4 |  
 | 
	
		
			
			| 5 |  | -App-wide support for 100% native navigation with potential isolation support.
 | 
	
		
			
			|  | 5 | +## Installation - iOS
 | 
	
		
			
			| 6 | 6 |  
 | 
	
		
			
			| 7 |  | -#### Setup your demo project
 | 
	
		
			
			|  | 7 | + * In your project folder run `npm install react-native-navigation --save`
 | 
	
		
			
			|  | 8 | + 
 | 
	
		
			
			|  | 9 | + * Add the native files of the dependency [react-native-controllers](https://github.com/wix/react-native-controllers) to your Xcode project:
 | 
	
		
			
			|  | 10 | +
 | 
	
		
			
			|  | 11 | +   * In Xcode, in Project Navigator (left pane), right-click on the `Libraries` > `Add files to [project name]`. Add `./node_modules/react-native-controllers/ios/ReactNativeControllers.xcodeproj` ([screenshots](https://facebook.github.io/react-native/docs/linking-libraries-ios.html#step-1))
 | 
	
		
			
			|  | 12 | + 
 | 
	
		
			
			|  | 13 | +   * In Xcode, in Project Navigator (left pane), click on your project (top) and select the `Build Phases` tab (right pane). In the `Link Binary With Libraries` section add `libReactNativeControllers.a` ([screenshots](https://facebook.github.io/react-native/docs/linking-libraries-ios.html#step-2))
 | 
	
		
			
			|  | 14 | +
 | 
	
		
			
			|  | 15 | +   * In Xcode, in Project Navigator (left pane), click on your project (top) and select the `Build Settings` tab (right pane). In the `Header Search Paths` section add `$(SRCROOT)/../node_modules/react-native-controllers/ios`. Make sure on the right to mark this new path `recursive` ([screenshots](https://facebook.github.io/react-native/docs/linking-libraries-ios.html#step-3))
 | 
	
		
			
			|  | 16 | +
 | 
	
		
			
			|  | 17 | + * In Xcode, under your project files, modify `AppDelegate.m` according to this [example](https://github.com/wix/react-native-navigation/blob/master/example/ios/example/AppDelegate.m)
 | 
	
		
			
			|  | 18 | + 
 | 
	
		
			
			|  | 19 | + * Make sure you are using react-native version >= 0.19.0
 | 
	
		
			
			|  | 20 | + 
 | 
	
		
			
			|  | 21 | +## Installation - Android
 | 
	
		
			
			|  | 22 | +
 | 
	
		
			
			|  | 23 | +Coming soon, not yet supported
 | 
	
		
			
			|  | 24 | +
 | 
	
		
			
			|  | 25 | +## Usage
 | 
	
		
			
			|  | 26 | +
 | 
	
		
			
			|  | 27 | +If you don't like reading, just jump into the fully working [example project](https://github.com/wix/react-native-navigation/tree/master/example).
 | 
	
		
			
			|  | 28 | +
 | 
	
		
			
			|  | 29 | +#### Step 1 - Change the way your app starts
 | 
	
		
			
			| 8 | 30 |  
 | 
	
		
			
			| 9 | 31 |  This would normally go in your `index.ios.js`
 | 
	
		
			
			| 10 | 32 |  
 | 
	
	
		
			
			|  | @@ -17,30 +39,31 @@ import './FirstTabScreen';
 | 
	
		
			
			| 17 | 39 |  import './SecondTabScreen';
 | 
	
		
			
			| 18 | 40 |  
 | 
	
		
			
			| 19 | 41 |  // start the app
 | 
	
		
			
			| 20 |  | -Navigation.startTabBasedApp([
 | 
	
		
			
			| 21 |  | -  {
 | 
	
		
			
			| 22 |  | -    title: 'One', // tab title
 | 
	
		
			
			| 23 |  | -    screen: 'example.FirstTabScreen', // unique ID registered with Navigation.registerScreen
 | 
	
		
			
			| 24 |  | -    icon: require('./img/one.png'), // local asset for tab icon (unselected state)
 | 
	
		
			
			| 25 |  | -    selectedIcon: require('./img/one_selected.png'), // local asset for tab icon (selected state)
 | 
	
		
			
			| 26 |  | -    screenTitle: 'Screen One', // navigation bar title
 | 
	
		
			
			| 27 |  | -    navigatorStyle: {} // style the navigator for this screen (optional)
 | 
	
		
			
			| 28 |  | -  },
 | 
	
		
			
			| 29 |  | -  {
 | 
	
		
			
			| 30 |  | -    title: 'Two',
 | 
	
		
			
			| 31 |  | -    screen: 'example.SecondTabScreen',
 | 
	
		
			
			| 32 |  | -    icon: require('./img/two.png'),
 | 
	
		
			
			| 33 |  | -    selectedIcon: require('./img/two_selected.png'),
 | 
	
		
			
			| 34 |  | -    screenTitle: 'Screen Two'
 | 
	
		
			
			| 35 |  | -  }
 | 
	
		
			
			| 36 |  | -]);
 | 
	
		
			
			|  | 42 | +Navigation.startTabBasedApp({
 | 
	
		
			
			|  | 43 | +  tabs: [
 | 
	
		
			
			|  | 44 | +    {
 | 
	
		
			
			|  | 45 | +      label: 'One',
 | 
	
		
			
			|  | 46 | +      screen: 'example.FirstTabScreen',
 | 
	
		
			
			|  | 47 | +      icon: require('../img/one.png'),
 | 
	
		
			
			|  | 48 | +      selectedIcon: require('../img/one_selected.png'),
 | 
	
		
			
			|  | 49 | +      title: 'Screen One'
 | 
	
		
			
			|  | 50 | +    },
 | 
	
		
			
			|  | 51 | +    {
 | 
	
		
			
			|  | 52 | +      label: 'Two',
 | 
	
		
			
			|  | 53 | +      screen: 'example.SecondTabScreen',
 | 
	
		
			
			|  | 54 | +      icon: require('../img/two.png'),
 | 
	
		
			
			|  | 55 | +      selectedIcon: require('../img/two_selected.png'),
 | 
	
		
			
			|  | 56 | +      title: 'Screen Two'
 | 
	
		
			
			|  | 57 | +    }
 | 
	
		
			
			|  | 58 | +  ]
 | 
	
		
			
			|  | 59 | +});
 | 
	
		
			
			| 37 | 60 |  ```
 | 
	
		
			
			| 38 | 61 |  
 | 
	
		
			
			| 39 |  | -#### Slightly modify your screen components
 | 
	
		
			
			|  | 62 | +#### Step 2 - Slightly modify your screen components
 | 
	
		
			
			| 40 | 63 |  
 | 
	
		
			
			| 41 | 64 |  Every screen that you want to be able to place in a tab, push to the navigation stack or present modally needs to follow two basic conventions:
 | 
	
		
			
			| 42 | 65 |  
 | 
	
		
			
			| 43 |  | -1. Normally your React components extend `React.Component`, in order to get access to the `navigator` you need to extend `Screen` instead.
 | 
	
		
			
			|  | 66 | +1. Normally your React components extend `React.Component`, in order to get access to the `navigator` instance you need to extend `Screen` instead.
 | 
	
		
			
			| 44 | 67 |  
 | 
	
		
			
			| 45 | 68 |  2. You need to register your component since it's displayed as a separate React root. Register a unique ID with `Navigation.registerScreen`.
 | 
	
		
			
			| 46 | 69 |  
 | 
	
	
		
			
			|  | @@ -65,9 +88,86 @@ class ExampleScreen extends Screen {
 | 
	
		
			
			| 65 | 88 |  Navigation.registerScreen('example.ScreenOne', () => ExampleScreen);
 | 
	
		
			
			| 66 | 89 |  ```
 | 
	
		
			
			| 67 | 90 |  
 | 
	
		
			
			| 68 |  | -#### Navigation API (how to push and pop)
 | 
	
		
			
			|  | 91 | +## Top Level API
 | 
	
		
			
			|  | 92 | +
 | 
	
		
			
			|  | 93 | +#### `Navigation`
 | 
	
		
			
			|  | 94 | +
 | 
	
		
			
			|  | 95 | +```js
 | 
	
		
			
			|  | 96 | +import { Navigation } from 'react-native-navigation';
 | 
	
		
			
			|  | 97 | +```
 | 
	
		
			
			|  | 98 | +
 | 
	
		
			
			|  | 99 | + * **registerScreen(screenID, generator)**
 | 
	
		
			
			|  | 100 | + 
 | 
	
		
			
			|  | 101 | +Every screen used must be registered with a unique name.
 | 
	
		
			
			|  | 102 | +
 | 
	
		
			
			|  | 103 | +```js
 | 
	
		
			
			|  | 104 | +Navigation.registerScreen('example.FirstTabScreen', () => FirstTabScreen);
 | 
	
		
			
			|  | 105 | +```
 | 
	
		
			
			|  | 106 | +
 | 
	
		
			
			|  | 107 | + * **startTabBasedApp(params)**
 | 
	
		
			
			|  | 108 | + 
 | 
	
		
			
			|  | 109 | +Change your app root into an app based on several tabs (usually 2-5), a very common pattern in iOS (like Facebook app or the iOS Contacts app). Every tab has its own navigation stack with a native nav bar.
 | 
	
		
			
			|  | 110 | +
 | 
	
		
			
			|  | 111 | +```js
 | 
	
		
			
			|  | 112 | +Navigation.startTabBasedApp({
 | 
	
		
			
			|  | 113 | +  tabs: [
 | 
	
		
			
			|  | 114 | +    {
 | 
	
		
			
			|  | 115 | +      label: 'One',
 | 
	
		
			
			|  | 116 | +      screen: 'example.FirstTabScreen',
 | 
	
		
			
			|  | 117 | +      icon: require('../img/one.png'),
 | 
	
		
			
			|  | 118 | +      selectedIcon: require('../img/one_selected.png'),
 | 
	
		
			
			|  | 119 | +      title: 'Screen One'
 | 
	
		
			
			|  | 120 | +    },
 | 
	
		
			
			|  | 121 | +    {
 | 
	
		
			
			|  | 122 | +      label: 'Two',
 | 
	
		
			
			|  | 123 | +      screen: 'example.SecondTabScreen',
 | 
	
		
			
			|  | 124 | +      icon: require('../img/two.png'),
 | 
	
		
			
			|  | 125 | +      selectedIcon: require('../img/two_selected.png'),
 | 
	
		
			
			|  | 126 | +      title: 'Screen Two'
 | 
	
		
			
			|  | 127 | +    }
 | 
	
		
			
			|  | 128 | +  ]
 | 
	
		
			
			|  | 129 | +});
 | 
	
		
			
			|  | 130 | +```
 | 
	
		
			
			| 69 | 131 |  
 | 
	
		
			
			| 70 |  | -This API is available through the `navigator` object. When your screen components extend `Screen`, they have `this.navigator` available and initialized.
 | 
	
		
			
			|  | 132 | + * **startSingleScreenApp(params)**
 | 
	
		
			
			|  | 133 | + 
 | 
	
		
			
			|  | 134 | +Change your app root into an app based on a single screen (like the iOS Calendar or Settings app). The screen will receive its own navigation stack with a native nav bar
 | 
	
		
			
			|  | 135 | +
 | 
	
		
			
			|  | 136 | +```js
 | 
	
		
			
			|  | 137 | +Navigation.startSingleScreenApp({
 | 
	
		
			
			|  | 138 | +  screen: {
 | 
	
		
			
			|  | 139 | +    screen: 'example.WelcomeScreen',
 | 
	
		
			
			|  | 140 | +    title: 'Welcome'
 | 
	
		
			
			|  | 141 | +  }
 | 
	
		
			
			|  | 142 | +});
 | 
	
		
			
			|  | 143 | +```
 | 
	
		
			
			|  | 144 | +
 | 
	
		
			
			|  | 145 | + * **showModal(params = {})**
 | 
	
		
			
			|  | 146 | +
 | 
	
		
			
			|  | 147 | +Show a screen as a modal.
 | 
	
		
			
			|  | 148 | + 
 | 
	
		
			
			|  | 149 | +```js
 | 
	
		
			
			|  | 150 | +Navigation.showModal({
 | 
	
		
			
			|  | 151 | +  title: "Modal",
 | 
	
		
			
			|  | 152 | +  screen: "example.ModalScreen"
 | 
	
		
			
			|  | 153 | +});
 | 
	
		
			
			|  | 154 | +```
 | 
	
		
			
			|  | 155 | +
 | 
	
		
			
			|  | 156 | + * **dismissModal(params = {})**
 | 
	
		
			
			|  | 157 | +
 | 
	
		
			
			|  | 158 | +Dismiss the current modal.
 | 
	
		
			
			|  | 159 | +
 | 
	
		
			
			|  | 160 | +```js
 | 
	
		
			
			|  | 161 | +Navigation.dismissModal();
 | 
	
		
			
			|  | 162 | +```
 | 
	
		
			
			|  | 163 | +
 | 
	
		
			
			|  | 164 | +## Screen API
 | 
	
		
			
			|  | 165 | +
 | 
	
		
			
			|  | 166 | +This API is relevant when in a screen context - it allows a screen to push other screens, pop screens, change its navigator style, etc. Access to this API is available through the `navigator` object. When your screen components extend `Screen`, they have `this.navigator` available and initialized.
 | 
	
		
			
			|  | 167 | +
 | 
	
		
			
			|  | 168 | + * **push(params)**
 | 
	
		
			
			|  | 169 | +
 | 
	
		
			
			|  | 170 | +Push a new screen into this screen's navigation stack.
 | 
	
		
			
			| 71 | 171 |  
 | 
	
		
			
			| 72 | 172 |  ```js
 | 
	
		
			
			| 73 | 173 |  this.navigator.push({
 | 
	
	
		
			
			|  | @@ -78,51 +178,38 @@ this.navigator.push({
 | 
	
		
			
			| 78 | 178 |    backButtonTitle: undefined, // override the back button title (optional)
 | 
	
		
			
			| 79 | 179 |    navigatorStyle: {} // override the navigator style for the pushed screen (optional)
 | 
	
		
			
			| 80 | 180 |  });
 | 
	
		
			
			| 81 |  | -
 | 
	
		
			
			| 82 |  | -this.navigator.pop({
 | 
	
		
			
			| 83 |  | -  animated: true // does the pop have transition animation or does it happen immediately (optional)
 | 
	
		
			
			| 84 |  | -});
 | 
	
		
			
			| 85 | 181 |  ```
 | 
	
		
			
			| 86 | 182 |  
 | 
	
		
			
			| 87 |  | -#### All types of apps you can create
 | 
	
		
			
			|  | 183 | + * **pop(params = {})**
 | 
	
		
			
			| 88 | 184 |  
 | 
	
		
			
			| 89 |  | -* App based on several tabs (usually 2-5), a very common pattern in iOS (like Facebook app or the iOS Contacts app). Every tab has its own navigation stack with a native nav bar.
 | 
	
		
			
			|  | 185 | +Pop the top screen from this screen's navigation stack.
 | 
	
		
			
			| 90 | 186 |  
 | 
	
		
			
			| 91 | 187 |  ```js
 | 
	
		
			
			| 92 |  | -Navigation.startTabBasedApp([
 | 
	
		
			
			| 93 |  | -  {
 | 
	
		
			
			| 94 |  | -    title: 'One', // tab title
 | 
	
		
			
			| 95 |  | -    screen: 'example.FirstTabScreen', // unique ID registered with Navigation.registerScreen
 | 
	
		
			
			| 96 |  | -    icon: require('./img/one.png'), // local asset for tab icon (unselected state)
 | 
	
		
			
			| 97 |  | -    selectedIcon: require('./img/one_selected.png'), // local asset for tab icon (selected state)
 | 
	
		
			
			| 98 |  | -    screenTitle: 'Screen One', // navigation bar title
 | 
	
		
			
			| 99 |  | -    navigatorStyle: {} // style the navigator for this screen (optional)
 | 
	
		
			
			| 100 |  | -  },
 | 
	
		
			
			| 101 |  | -  {
 | 
	
		
			
			| 102 |  | -    title: 'Two',
 | 
	
		
			
			| 103 |  | -    screen: 'example.SecondTabScreen',
 | 
	
		
			
			| 104 |  | -    icon: require('./img/two.png'),
 | 
	
		
			
			| 105 |  | -    selectedIcon: require('./img/two_selected.png'),
 | 
	
		
			
			| 106 |  | -    screenTitle: 'Screen Two'
 | 
	
		
			
			| 107 |  | -  }
 | 
	
		
			
			| 108 |  | -]);
 | 
	
		
			
			|  | 188 | +this.navigator.pop({
 | 
	
		
			
			|  | 189 | +  animated: true // does the pop have transition animation or does it happen immediately (optional)
 | 
	
		
			
			|  | 190 | +});
 | 
	
		
			
			| 109 | 191 |  ```
 | 
	
		
			
			| 110 | 192 |  
 | 
	
		
			
			| 111 |  | -* App based on a single screen (like the iOS Calendar or Settings app). The screen will receive its own navigation stack with a native nav bar.
 | 
	
		
			
			|  | 193 | + * **showModal(params = {})**
 | 
	
		
			
			| 112 | 194 |  
 | 
	
		
			
			|  | 195 | +Show a screen as a modal.
 | 
	
		
			
			|  | 196 | + 
 | 
	
		
			
			| 113 | 197 |  ```js
 | 
	
		
			
			| 114 |  | -Navigation.startSingleScreenApp({
 | 
	
		
			
			| 115 |  | -  screen: 'example.WelcomeScreen', // unique ID registered with Navigation.registerScreen
 | 
	
		
			
			| 116 |  | -  screenTitle: 'Welcome', // navigation bar title
 | 
	
		
			
			| 117 |  | -  navigatorStyle: {} // style the navigator for this screen (optional)
 | 
	
		
			
			|  | 198 | +this.navigator.showModal({
 | 
	
		
			
			|  | 199 | +  title: "Modal",
 | 
	
		
			
			|  | 200 | +  screen: "example.ModalScreen"
 | 
	
		
			
			| 118 | 201 |  });
 | 
	
		
			
			| 119 | 202 |  ```
 | 
	
		
			
			| 120 | 203 |  
 | 
	
		
			
			| 121 |  | -It is also possible to switch between types of apps while the app is running. This can be useful for example when switching from a login mode (which has no tabs = `startSingleScreenApp`) to the actual app itself (which has tabs = `startTabBasedApp`). Please note that when switching formats, the entire "old" app will be unmounted and released.
 | 
	
		
			
			|  | 204 | + * **dismissModal(params = {})**
 | 
	
		
			
			| 122 | 205 |  
 | 
	
		
			
			| 123 |  | -> Tip: The other pattern of implementing login is having just one app type (like tabs) and showing the login dialog as a modal that hides the tabs when the app is launched. When login is completed, this modal is dismissed.
 | 
	
		
			
			|  | 206 | +Dismiss the current modal.
 | 
	
		
			
			|  | 207 | +
 | 
	
		
			
			|  | 208 | +```js
 | 
	
		
			
			|  | 209 | +this.navigator.dismissModal();
 | 
	
		
			
			|  | 210 | +```
 | 
	
		
			
			| 124 | 211 |  
 | 
	
		
			
			| 125 |  | -#### Styling the navigator
 | 
	
		
			
			|  | 212 | +## Styling the navigator
 | 
	
		
			
			| 126 | 213 |  
 | 
	
		
			
			| 127 | 214 |  You can style the navigator appearance and behavior by passing a `navigatorStyle` object. This object can be passed when the screen is originally created; can be defined per-screen in the `static navigatorStyle = {};` on `Screen`; and can be overridden when a screen is pushed.
 | 
	
		
			
			| 128 | 215 |  
 |