Browse Source

Update README.md

Tal Kol 8 years ago
parent
commit
81a498e39d
1 changed files with 98 additions and 74 deletions
  1. 98
    74
      README.md

+ 98
- 74
README.md View File

@@ -11,6 +11,8 @@ App-wide support for 100% native navigation with an easy cross-platform interfac
11 11
 * [Screen API](#screen-api)
12 12
 * [Styling the navigator](#styling-the-navigator)
13 13
 * [Adding buttons to the navigator](#adding-buttons-to-the-navigator)
14
+* [Release Notes](RELEASES.md)
15
+* [License](#license)
14 16
 
15 17
 ## Installation - iOS
16 18
 
@@ -35,7 +37,10 @@ Coming soon, not yet supported
35 37
 
36 38
 ## Usage
37 39
 
38
-If you don't like reading, just jump into the fully working [example project](https://github.com/wix/react-native-navigation/tree/master/example).
40
+If you don't like reading, just jump into the fully working example projects:
41
+
42
+* [example](example) - Example project showing the best practice use of this package. Shows many navigation features.
43
+* [redux-example](example-redux) - Best practice use of this package in a [redux](https://github.com/reactjs/redux)-based. project
39 44
 
40 45
 #### Step 1 - Change the way your app starts
41 46
 
@@ -44,17 +49,15 @@ This would normally go in your `index.ios.js`
44 49
 ```js
45 50
 import { Navigation } from 'react-native-navigation';
46 51
 
47
-// import the components for your root screens (or the packager will not bundle them)
48
-// they all need to be registered with Navigation.registerScreen
49
-import './FirstTabScreen';
50
-import './SecondTabScreen';
52
+import { registerScreens } from './screens';
53
+registerScreens(); // this is where you register all of your app's screens
51 54
 
52 55
 // start the app
53 56
 Navigation.startTabBasedApp({
54 57
   tabs: [
55 58
     {
56 59
       label: 'One',
57
-      screen: 'example.FirstTabScreen',
60
+      screen: 'example.FirstTabScreen', // this is a registered name for a screen
58 61
       icon: require('../img/one.png'),
59 62
       selectedIcon: require('../img/one_selected.png'),
60 63
       title: 'Screen One'
@@ -70,33 +73,25 @@ Navigation.startTabBasedApp({
70 73
 });
71 74
 ```
72 75
 
73
-#### Step 2 - Slightly modify your screen components
74
-
75
-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:
76
-
77
-1. Normally your React components extend `React.Component`, in order to get access to the `navigator` instance you need to extend `Screen` instead.
76
+#### Step 2 - Register all of your screen components
78 77
 
79
-2. You need to register your component since it's displayed as a separate React root. Register a unique ID with `Navigation.registerScreen`.
78
+Every screen that you want to be able to place in a tab, push to the navigation stack or present modally needs to be registered. We recommend doing this in a central place, like [`screens/index.js`](example/src/screens/index.js). 
80 79
 
81 80
 > Note: Since your screens will potentially be bundled with other packages, your registered name must be **unique**! Follow a namespacing convention like `packageName.ScreenName`.
82 81
 
83 82
 ```js
84
-import { Navigation, Screen } from 'react-native-navigation';
83
+import { Navigation } from 'react-native-navigation';
85 84
 
86
-class ExampleScreen extends Screen {
87
-  static navigatorStyle = {}; // style the navigator for this screen (optional)
88
-  constructor(props) {
89
-    super(props);
90
-  }
91
-  render() {
92
-    return (
93
-      <View style={styles.container}>...</View>
94
-    );
95
-  }
96
-}
85
+import FirstTabScreen from './FirstTabScreen';
86
+import SecondTabScreen from './SecondTabScreen';
87
+import PushedScreen from './PushedScreen';
97 88
 
98
-// register all screens with Navigation.registerScreen
99
-Navigation.registerScreen('example.ScreenOne', () => ExampleScreen);
89
+// register all screens of the app (including internal ones)
90
+export function registerScreens() {
91
+  Navigation.registerComponent('example.FirstTabScreen', () => FirstTabScreen);
92
+  Navigation.registerComponent('example.SecondTabScreen', () => SecondTabScreen);
93
+  Navigation.registerComponent('example.PushedScreen', () => PushedScreen);
94
+}
100 95
 ```
101 96
 
102 97
 ## Top Level API
@@ -107,12 +102,16 @@ Navigation.registerScreen('example.ScreenOne', () => ExampleScreen);
107 102
 import { Navigation } from 'react-native-navigation';
108 103
 ```
109 104
 
110
- * **registerScreen(screenID, generator)**
105
+ * **registerComponent(screenID, generator, store = undefined, Provider = undefined)**
111 106
  
112
-Every screen used must be registered with a unique name.
107
+Every screen component in your app must be registered with a unique name. The component itself is a traditional React component extending `React.Component`. 
113 108
 
114 109
 ```js
115
-Navigation.registerScreen('example.FirstTabScreen', () => FirstTabScreen);
110
+// not using redux (just ignore the last 2 arguments)
111
+Navigation.registerComponent('example.FirstTabScreen', () => FirstTabScreen);
112
+
113
+// using redux, pass your store and the Provider object from react-redux
114
+Navigation.registerComponent('example.FirstTabScreen', () => FirstTabScreen, store, Provider);
116 115
 ```
117 116
 
118 117
  * **startTabBasedApp(params)**
@@ -193,18 +192,26 @@ Dismiss the current modal.
193 192
 Navigation.dismissModal({
194 193
   animationType: 'slide-down' // 'none' / 'slide-down' , dismiss animation for the modal (optional, default 'slide-down')
195 194
 });
195
+```
196
+
197
+ * **registerScreen(screenID, generator)**
198
+ 
199
+This is an internal function you probably don't want to use directly. If your screen components extend `Screen` directly (`import { Screen } from 'react-native-navigation'`), you can register them directly with `registerScreen` instead of with `registerComponent`. The main benefit of using `registerComponent` is that it wraps your regular screen component with a `Screen` automatically.
200
+
201
+```js
202
+Navigation.registerScreen('example.AdvancedScreen', () => AdvancedScreen);
196 203
 ```
197 204
 
198 205
 ## Screen API
199 206
 
200
-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.
207
+This API is relevant when in a screen component 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 that is passed to your component through `props`.
201 208
 
202 209
  * **push(params)**
203 210
 
204 211
 Push a new screen into this screen's navigation stack.
205 212
 
206 213
 ```js
207
-this.navigator.push({
214
+this.props.navigator.push({
208 215
   screen: 'example.ScreenThree', // unique ID registered with Navigation.registerScreen
209 216
   title: undefined, // navigation bar title of the pushed screen (optional)
210 217
   passProps: {}, // simple serializable object that will pass as props to the pushed screen (optional)
@@ -219,7 +226,7 @@ this.navigator.push({
219 226
 Pop the top screen from this screen's navigation stack.
220 227
 
221 228
 ```js
222
-this.navigator.pop({
229
+this.props.navigator.pop({
223 230
   animated: true // does the pop have transition animation or does it happen immediately (optional)
224 231
 });
225 232
 ```
@@ -229,7 +236,7 @@ this.navigator.pop({
229 236
 Pop all the screens until the root from this screen's navigation stack.
230 237
 
231 238
 ```js
232
-this.navigator.popToRoot({
239
+this.props.navigator.popToRoot({
233 240
   animated: true // does the pop have transition animation or does it happen immediately (optional)
234 241
 });
235 242
 ```
@@ -239,7 +246,7 @@ this.navigator.popToRoot({
239 246
 Reset the screen's navigation stack to a new screen (the stack root is changed).
240 247
 
241 248
 ```js
242
-this.navigator.resetTo({
249
+this.props.navigator.resetTo({
243 250
   screen: 'example.ScreenThree', // unique ID registered with Navigation.registerScreen
244 251
   title: undefined, // navigation bar title of the pushed screen (optional)
245 252
   passProps: {}, // simple serializable object that will pass as props to the pushed screen (optional)
@@ -253,7 +260,7 @@ this.navigator.resetTo({
253 260
 Show a screen as a modal.
254 261
  
255 262
 ```js
256
-this.navigator.showModal({
263
+this.props.navigator.showModal({
257 264
   screen: "example.ModalScreen", // unique ID registered with Navigation.registerScreen
258 265
   title: "Modal", // title of the screen as appears in the nav bar (optional)
259 266
   passProps: {}, // simple serializable object that will pass as props to the modal (optional)
@@ -267,9 +274,18 @@ this.navigator.showModal({
267 274
 Dismiss the current modal.
268 275
 
269 276
 ```js
270
-this.navigator.dismissModal({
277
+this.props.navigator.dismissModal({
271 278
   animationType: 'slide-down' // 'none' / 'slide-down' , dismiss animation for the modal (optional, default 'slide-down')
272 279
 });
280
+```
281
+
282
+ * **setOnNavigatorEvent(callback)**
283
+
284
+Set a handler for navigator events (like nav button press). This would normally go in your component constructor.
285
+
286
+```js
287
+// this.onNavigatorEvent will be our handler
288
+this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
273 289
 ```
274 290
 
275 291
  * **setButtons(params = {})**
@@ -277,7 +293,7 @@ this.navigator.dismissModal({
277 293
 Set buttons dynamically on the navigator. If your buttons don't change during runtime, see "Adding buttons to the navigator" below to add them using `static navigatorButtons = {...};`.
278 294
 
279 295
 ```js
280
-this.navigator.setButtons({
296
+this.props.navigator.setButtons({
281 297
   leftButtons: [], // see "Adding buttons to the navigator" below for format (optional)
282 298
   rightButtons: [], // see "Adding buttons to the navigator" below for format (optional)
283 299
   animated: true // does the change have transition animation or does it happen immediately (optional)
@@ -289,7 +305,7 @@ this.navigator.setButtons({
289 305
 Set the nav bar title dynamically. If your title doesn't change during runtime, set it when the screen is defined / pushed.
290 306
 
291 307
 ```js
292
-this.navigator.setTitle({
308
+this.props.navigator.setTitle({
293 309
   title: "Dynamic Title" // the new title of the screen as appears in the nav bar
294 310
 });
295 311
 ```
@@ -299,7 +315,7 @@ this.navigator.setTitle({
299 315
 Toggle the side menu drawer assuming you have one in your app.
300 316
 
301 317
 ```js
302
-this.navigator.toggleDrawer({
318
+this.props.navigator.toggleDrawer({
303 319
   side: 'left', // the side of the drawer since you can have two, 'left' / 'right'
304 320
   animated: true // does the toggle have transition animation or does it happen immediately (optional)
305 321
 });
@@ -307,7 +323,25 @@ this.navigator.toggleDrawer({
307 323
 
308 324
 ## Styling the navigator
309 325
 
310
-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.
326
+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 by setting `static navigatorStyle = {};` on the screen component; and can be overridden when a screen is pushed.
327
+
328
+The easiest way to style your screen is by adding `static navigatorStyle = {};` to your screen React component definition.
329
+
330
+```js
331
+export default class StyledScreen extends Component {
332
+  static navigatorStyle = {
333
+    drawUnderNavBar: true,
334
+    navBarTranslucent: true
335
+  };
336
+  constructor(props) {
337
+    super(props);
338
+  }
339
+  render() {
340
+    return (
341
+      <View style={{flex: 1}}>...</View>
342
+     );
343
+  }
344
+```
311 345
 
312 346
 #### Style object format
313 347
 
@@ -334,44 +368,12 @@ You can style the navigator appearance and behavior by passing a `navigatorStyle
334 368
 
335 369
 All supported styles are defined [here](https://github.com/wix/react-native-controllers#styling-navigation). There's also an example project there showcasing all the different styles.
336 370
 
337
-#### Screen-specific style example
338
-
339
-Define a screen-specific style by adding `static navigatorStyle = {...};` to the Screen definition.
340
-
341
-```js
342
-class StyledScreen extends Screen {
343
-  static navigatorStyle = {
344
-    drawUnderNavBar: true,
345
-    drawUnderTabBar: true,
346
-    navBarTranslucent: true
347
-  };
348
-  constructor(props) {
349
-    super(props);
350
-  }
351
-  render() {
352
-    return (
353
-      <View style={{flex: 1}}>...</View>
354
-     );
355
-  }
356
-```
357
-
358 371
 ## Adding buttons to the navigator
359 372
 
360
-Nav bar buttons can be defined per-screen by adding `static navigatorButtons = {...};` on the Screen definition. Handle onPress events for the buttons by overriding the Screen's `onNavigatorEvent(event)` method.
361
-
362
-#### Buttons object format
363
-
364
-```js
365
-{
366
-  rightButtons: [], // buttons for the right side of the nav bar (optional)
367
-  leftButtons: [] // buttons for the left side of the nav bar (optional)
368
-}
369
-```
370
-
371
-#### Screen-specific buttons example
373
+Nav bar buttons can be defined per-screen by adding `static navigatorButtons = {...};` on the screen component definition. Handle onPress events for the buttons by setting your handler with `navigator.setOnNavigatorEvent(callback)`.
372 374
 
373 375
 ```js
374
-class FirstTabScreen extends Screen {
376
+class FirstTabScreen extends Component {
375 377
   static navigatorButtons = {
376 378
     rightButtons: [
377 379
       {
@@ -387,6 +389,8 @@ class FirstTabScreen extends Screen {
387 389
   };
388 390
   constructor(props) {
389 391
     super(props);
392
+    // if you want to listen on navigator events, set this up
393
+    this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
390 394
   }
391 395
   onNavigatorEvent(event) { // this is the onPress handler for the two buttons together
392 396
     if (event.id == 'edit') { // this is the same id field from the static navigatorButtons definition
@@ -402,3 +406,23 @@ class FirstTabScreen extends Screen {
402 406
      );
403 407
   }
404 408
 ```
409
+
410
+#### Buttons object format
411
+
412
+```js
413
+{
414
+  rightButtons: [{ // buttons for the right side of the nav bar (optional)
415
+    title: 'Edit', // if you want a textual button
416
+    icon: require('../../img/navicon_edit.png'), // if you want an image button
417
+    id: 'compose', // id of the button which will pass to your press event handler
418
+    testID: 'e2e_is_awesome' // if you have e2e tests, use this to find your button
419
+  }],
420
+  leftButtons: [] // buttons for the left side of the nav bar (optional)
421
+}
422
+```
423
+
424
+## License
425
+
426
+The MIT License.
427
+
428
+See [LICENSE](LICENSE)