UNPKG

15.8 kBMarkdownView Raw
1# react-native-screens
2
3This project aims to expose native navigation container components to React Native. It is not designed to be used as a standalone library but rather as a dependency of a [full-featured navigation library](https://github.com/react-navigation/react-navigation).
4
5## How can I take advantage of that?
6
7Screens are already integrated with the React Native's most popular navigation library [react-navigation](https://github.com/react-navigation/react-navigation) and [Expo](https://expo.io).
8Read usage guide depending on if you are [using Expo](#usage-in-expo-with-react-navigation) or [not](#usage-with-react-navigation-without-expo).
9
10## Supported react-native version
11
12Since version 2.0.0 react-native-screens requires RN v0.60+. Check 1.0.0-alpha for Expo support or older versions of React Native.
13
14## Usage with [react-navigation](https://github.com/react-navigation/react-navigation) (without Expo)
15
16Screens support is built into [react-navigation](https://github.com/react-navigation/react-navigation) starting from version [2.14.0](https://github.com/react-navigation/react-navigation/releases/tag/2.14.0) for all the different navigator types (stack, tab, drawer, etc). We plan on adding it to other navigators in near future.
17
18To configure react-navigation to use screens instead of plain RN Views for rendering screen views, follow the steps below:
19
201. Add this library as a dependency to your project:
21
22```bash
23yarn add react-native-screens
24```
25
262.Link native modules this library ships with into your app:
27
28```bash
29react-native link react-native-screens
30```
31
32> If you are not familiar with the concept of linking libraries [read on here](https://facebook.github.io/react-native/docs/linking-libraries-ios).
33
343.Enable screens support before any of your navigation screen renders. Add the following code to your main application file (e.g. App.js):
35
36```js
37import { enableScreens } from 'react-native-screens';
38
39enableScreens();
40```
41
42Note that the above code need to execute before first render of a navigation screen. You can check Example's app [App.js](https://github.com/kmagiera/react-native-screens/blob/master/Example/App.js#L16) file as a reference.
43
444. Make sure that the version of [react-navigation](https://github.com/react-navigation/react-navigation) you are using is 2.14.0 or higher
45
465. You are all set 🎉 – when screens are enabled in your application code react-navigation will automatically use them instead of relying on plain React Native Views.
47
48## Usage in Expo with [react-navigation](https://github.com/react-navigation/react-navigation) v1.0.0
49
50Screens support is built into Expo [SDK 30](https://blog.expo.io/expo-sdk-30-0-0-is-now-available-e64d8b1db2a7) and react-navigation starting from [2.14.0](https://github.com/react-navigation/react-navigation/releases/tag/2.14.0). Make sure your app use these versions before you start.
51
521. Add screens library as dependency to your project – you can skip this step when using snack as the dependency will be imported when you import it in one of the JS files
53
54```bash
55yarn add react-native-screens
56```
57
582. Open your App.js file and add the following snippet somewhere near the top of the file (e.g. right after import statements):
59
60```js
61import { enableScreens } from 'react-native-screens';
62
63enableScreens();
64```
65
663. That's all 🎉 – enjoy faster navigation in your Expo app. Keep in mind screens are in pretty early phase so please report if you discover some issues.
67
68## Interop with [react-native-navigation](https://github.com/wix/react-native-navigation)
69
70React-native-navigation library already uses native containers for rendering navigation scenes so wrapping these scenes with `<ScreenContainer>` or `<Screen>` component does not provide any benefits. Yet if you would like to build a component that uses screens primitives under the hood (for example a view pager component) it is safe to use `<ScreenContainer>` and `<Screen>` components for that as these work out of the box when rendered on react-native-navigation scenes.
71
72## Using native stack navigator
73
74In order to take advantage of the native stack navigator primitive introduced in version 2.0 you need to use navigator creator function exported by react-native-screens package:
75
76```js
77import createNativeStackNavigator from 'react-native-screens/createNativeStackNavigator';
78```
79
80Then replace places when you use `createStackNavigator` with `createNativeStackNavigator`. Note that not all the screen customization options are supported. There are some technical limitations for implementing some of the stack header options. Documenting the supported parameters is on an immediate roadmap and will be available soon.
81
82## Interop with other libraries
83
84This library should work out of the box with all existing react-native libraries. If you experience problems with interoperability please [report an issue](https://github.com/kmagiera/react-native-screens/issues).
85
86## Guide for navigation library authors
87
88If you are building navigation library you may want to use react-native-screens to have a control which parts of the react component tree are attached to the native view hierarchy.
89To do that react-native-screens provides you with two components documented below:
90
91### `<ScreenContainer/>`
92
93This component is a container for one or more `Screen` components.
94It does not accept other component types as direct children.
95The role of the container is to control which of its children screens should be attached to the view hierarchy.
96It does that by monitoring the `active` property of each of its children.
97It is possible to have as many `active` children as you'd like but in order for the component to be the most efficient we should keep the number of active screens to a minimum.
98In a case of a stack navigator or tabs navigator we only want to have one active screen (the top most view on a stack or the selected tab).
99While transitioning between views we may want to activate a second screen for the duration of the transition, and then go back to just one active screen.
100
101### `<Screen/>`
102
103This component is a container for views we want to display on a navigation screen.
104It is designed to only be rendered as a direct child of `ScreenContainer`.
105In addition to plain React Native [View props](http://facebook.github.io/react-native/docs/view#props) this component only accepts a single additional property called `active`.
106When `active` is set to `0`, the parent container will detach its views from the native view hierarchy.
107Otherwise the views will be attached as long as the parent container is attached too.
108
109#### Example
110
111```js
112<ScreenContainer>
113 <Screen>{tab1}</Screen>
114 <Screen active={1}>{tab2}</Screen>
115 <Screen>{tab3}</Screen>
116</ScreenContainer>
117```
118
119### `<ScreenStack>`
120
121Screen stack component expects one or more `Screen` components as direct children and renders them in a platform native stack container (for iOS it is `UINavigationController` and for Android inside `Fragment` container). For `Screen` components placed as children of `ScreenStack` the `active` property is ignored and instead the screen that corresponds to the last child is rendered as active. All type of updates done to the list of children are acceptable, when the top element is exchanged the container will use platform default (unless customized) animation to transition between screens.
122
123`StackScreen` extends the capabilities of `Screen` component to allow additional customizations and to make it possible to handle events such as using hardware back or back gesture to dismiss the top screen. Below is the list of additional properties that can be used for `Screen` component:
124
125#### `onDismissed`
126
127A callback that gets called when the current screen is dismissed by hardware back (on Android) or dismiss gesture (swipe back or down). The callback takes no arguments.
128
129#### `stackAnimation`
130
131Allows for the customization of how the given screen should appear/dissapear when pushed or popped at the top of the stack. The followin values are currently supported:
132 - `"default"` – uses a platform default animation
133 - `"fade"` – fades screen in or out
134 - `"flip"` – flips the screen, requires `stackPresentation: "modal"` (iOS only)
135 - `"none"` – the screen appears/dissapears without an animation
136
137 #### `stackPresentation`
138
139Defines how the method that should be used to present the given screen. It is a separate property from `stackAnimation` as the presentation mode can carry additional semantic. The allowed values are:
140 - `"push"` – the new screen will be pushed onto a stack which on iOS means that the default animation will be slide from the side, the animation on Android may vary depending on the OS version and theme.
141 - `"modal"` – the new screen will be presented modally. In addition this allow for a nested stack to be rendered inside such screens
142 - `"transparentModal"` – the new screen will be presented modally but in addition the second to last screen will remain attached to the stack container such that if the top screen is non opaque the content below can still be seen. If `"modal"` is used instead the below screen will get unmounted as soon as the transition ends.
143
144### `<ScreenStackHeaderConfig>`
145
146The config component is expected to be rendered as a direct children of `<Screen>`. It provides an ability to configure native navigation header that gets rendered as a part of native screen stack. The component acts as a "virtual" element that is not directly rendered under `Screen`. You can use its properties to customize platform native header for the parent screen and also render react-native components that you'd like to be displayed inside the header (e.g. in the title are or on the side).
147
148Along with this component properties that can be used to customize header behavior one can also use one or the below component containers to render custom react-native content in different areas of the native header:
149 - `ScreenStackHeaderCenterView` – the childern will render in the center of the native navigation bar.
150 - `ScreenStackHeaderRightView` – the children will render on the right hand side of the navigation bar (or on the left hand side in case LTR locales are set on the user's device).
151 - `ScreenStackHeaderLeftView` – the children will render on the left hand side of the navigation bar (or on the right hand side in case LTR locales are set on the user's device).
152
153Below is a list of properties that can be set with `ScreenStackHeaderConfig` component:
154
155
156#### `hidden`
157
158When set to `true` the header will be hidden while the parent `Screen` is on the top of the stack. The default value is `false`.
159
160#### `color`
161
162Controls the color of items rendered on the header. This includes back icon, back text (iOS only) and title text. If you want the title to have different color use `titleColor` property.
163
164#### `title`
165
166String that representing screen title that will get rendered in the middle section of the header. On iOS the title is centered on the header while on Android it is aligned to the left and placed next to back button (if one is present).
167
168#### `titleFontFamily`
169
170Customize font family to be used for the title.
171
172#### `titleFontSize`
173
174Customize the size of the font to be used for the title.
175
176#### `titleColor`
177
178Allows for setting text color of the title.
179
180#### `backgroundColor`
181
182Controlls the color of the navigation header.
183
184#### `hideShadow`
185
186Boolean that allows for disabling drop shadow under navigation header. The default value is `true`.
187
188#### `hideBackButton`
189
190If set to `true` the back button will not be rendered as a part of navigation header.
191
192#### `gestureEnabled`
193
194When set to `false` the back swipe gesture will be disabled when the parent `Screen` is on top of the stack. The default value is `true`.
195
196#### `translucent` (iOS only)
197
198When set to `true`, it makes native navigation bar on iOS semi transparent with blur effect. It is a common way of presenting navigation bar introduced in iOS 11. The default value is `false`.
199
200#### `backTitle` (iOS only)
201
202Allows for controlling the string to be rendered next to back button. By default iOS uses the title of the previous screen.
203
204#### `backTitleFontFamily` (iOS only)
205
206Allows for customizing font family to be used for back button title on iOS.
207
208#### `backTitleFontSize` (iOS only)
209
210Allows for customizing font size to be used for back button title on iOS.
211
212#### `largeTitle` (iOS only)
213
214When set to `true` it makes the title display using the large title effect.
215
216#### `largeTitleFontFamily` (iOS only)
217
218Customize font family to be used for the large title.
219
220#### `largeTitleFontSize` (iOS only)
221
222Customize the size of the font to be used for the large title.
223
224## Guide for native component authors
225
226If you are adding a new native component to be used from the React Native app, you may want it to respond to navigation lifecycle events.
227
228Good example is a map component that shows current user location. When component is on the top-most screen it should register for location updates and display users location on the map. But if we navigate away from a screen that has a map, e.g. by pushing new screen on top of it or if it is in one of a tabs and user just switched to the previous app, we may want to stop listening to location updates.
229
230In order to achieve that we need to know at the native component level when our native view goes out of sight. With react-native-screens you can do that in the following way:
231
232### Navigation lifecycle on iOS
233
234In order for your native view on iOS to be notified when its parent navigation container goes into background override `didMoveToWindow` method:
235
236```objective-c
237- (void)didMoveToWindow
238{
239 [super didMoveToWindow];
240 BOOL isVisible = self.superview && self.window;
241 if (isVisible) {
242 // navigation container this view belongs to became visible
243 } else {
244 // we are in a background
245 }
246}
247```
248
249You can check our example app for a fully functional demo see [RNSSampleLifecycleAwareView.m](https://github.com/kmagiera/react-native-screens/blob/master/Example/ios/ScreensExample/RNSSampleLifecycleAwareView.m) for more details.
250
251### Navigation lifecycle on Android
252
253On Android you can use [LifecycleObserver](https://developer.android.com/reference/android/arch/lifecycle/LifecycleObserver) interface which is a part of Android compat library to make your view handle lifecycle events.
254Check [LifecycleAwareView.java](https://github.com/kmagiera/react-native-screens/blob/master/Example/android/app/src/main/java/com/swmansion/rnscreens/example/LifecycleAwareView.java) from our example app for more details on that.
255
256In addition to that you will need to register for receiving these updates. This can be done using [`LifecycleHelper.register`](https://github.com/kmagiera/react-native-screens/blob/master/android/src/main/java/com/swmansion/rnscreens/LifecycleHelper.java#L50).
257Remember to call [`LifecycleHelper.unregister`](https://github.com/kmagiera/react-native-screens/blob/master/android/src/main/java/com/swmansion/rnscreens/LifecycleHelper.java#L59) before the view is dropped.
258Please refer to [SampleLifecycleAwareViewManager.java](https://github.com/kmagiera/react-native-screens/blob/master/Example/android/app/src/main/java/com/swmansion/rnscreens/example/SampleLifecycleAwareViewManager.java) from our example app to see what are the best ways of using the above methods.
259
260## License
261
262React native screens library is licensed under [The MIT License](LICENSE).
263
264## Credits
265
266This project is supported by amazing people from [Expo.io](https://expo.io) and [Software Mansion](https://swmansion.com)
267
268[![expo](https://avatars2.githubusercontent.com/u/12504344?v=3&s=100 'Expo.io')](https://expo.io)
269[![swm](https://avatars1.githubusercontent.com/u/6952717?v=3&s=100 'Software Mansion')](https://swmansion.com)