|
@@ -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
|
|