├── components ├── PickerIOS.md ├── WebView.md ├── TouchableWithoutFeedback.md ├── ActivityIndicatorIOS.md ├── TouchableOpacity.md ├── SwitchIOS.md ├── SliderIOS.md ├── TouchableHighlight.md ├── DatePickerIOS.md ├── TextInput.md ├── MapView.md ├── TabBarIOS.md ├── NavigatorIOS.md ├── View.md ├── ListView.md ├── Navigator.md ├── ScrollView.md ├── Text.md └── Image.md ├── quick-start ├── Video.md ├── GettingStarted.md └── Tutorial.md ├── apis ├── LayoutAnimation.md ├── Animation.md ├── AppRegistry.md ├── StyleSheet.md ├── VibrationIOS.md ├── InteractionManager.md ├── PixelRatio.md ├── LinkingIOS.md ├── AlertIOS.md ├── StatusBarIOS.md ├── AppStateIOS.md ├── CameraRoll.md ├── PanResponder.md ├── NetInfo.md ├── AsyncStorage.md └── PushNotificationIOS.md ├── polyfills ├── Flexbox.md ├── Network.md ├── Geolocation.md └── Timers.md ├── guides ├── Debugging.md ├── LinkingLibraries.md ├── Testing.md ├── Style.md ├── GestureResponderSystem.md └── NativeModulesIOS.md └── README.md /components/PickerIOS.md: -------------------------------------------------------------------------------- 1 | ## Props 2 | 3 | **onValueChange** function 4 | 5 | **selectedValue** any -------------------------------------------------------------------------------- /quick-start/Video.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: videos 3 | title: Videos 4 | layout: docs 5 | category: Quick Start 6 | permalink: docs/videos.html 7 | next: style 8 | --- 9 | 10 | # Videos 11 | 12 | 传送门:http://facebook.github.io/react-native/docs/videos.html 13 | -------------------------------------------------------------------------------- /components/WebView.md: -------------------------------------------------------------------------------- 1 | ## Props 2 | 3 | **automaticallyAdjustContentInsets** bool 4 | 5 | **contentInset** {top: number, left: number, bottom: number, right: number} 6 | 7 | **onNavigationStateChange** function 8 | 9 | **renderError** function 10 | 11 | **renderLoading** function 12 | 13 | **shouldInjectAJAXHandler** bool 14 | 15 | **startInLoadingState** bool 16 | 17 | **style** View#style 18 | 19 | **url** string # -------------------------------------------------------------------------------- /apis/LayoutAnimation.md: -------------------------------------------------------------------------------- 1 | All rights reserved. 2 | 3 | This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. 4 | 5 | @flow 6 | 7 | ## Methods 8 | 9 | static **configureNext**(config: Config, onAnimationDidEnd?: Function, onError?: Function) 10 | 11 | static **create**(duration: number, type, creationProp) -------------------------------------------------------------------------------- /apis/Animation.md: -------------------------------------------------------------------------------- 1 | All rights reserved. 2 | 3 | This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. 4 | 5 | @flow 6 | 7 | ## Methods 8 | 9 | static **startAnimation**(node: any, duration: number, delay: number, easing: (string | EasingFunction), properties: {[key: string]: any}) 10 | 11 | static **stopAnimation**(tag: number) -------------------------------------------------------------------------------- /components/TouchableWithoutFeedback.md: -------------------------------------------------------------------------------- 1 | Do not use unless you have a very good reason. All the elements that respond to press should have a visual feedback when touched. This is one of the primary reason a "web" app doesn't feel "native". 2 | 3 | ## Props 4 | 5 | **onLongPress** function 6 | 7 | **onPress** function 8 | 9 | Called when the touch is released, but not if cancelled (e.g. by a scroll that steals the responder lock). 10 | 11 | **onPressIn** function 12 | 13 | **onPressOut** function -------------------------------------------------------------------------------- /components/ActivityIndicatorIOS.md: -------------------------------------------------------------------------------- 1 | ##Props 2 | 3 | **animating** bool 4 | 5 | Whether to show the indicator (true, the default) or hide it (false). 6 | 7 | **color** string 8 | 9 | The foreground color of the spinner (default is gray). 10 | 11 | **size** enum('small', 'large') 12 | 13 | Size of the indicator. Small has a height of 20, large has a height of 36. 14 | 15 | ## 属性 16 | 17 | **animating** bool 18 | 19 | 是否显示指示器,true表示显示,false表示隐藏。它的默认值为true。 20 | 21 | **color** string 22 | 23 | 微调器(spinner)的前景色(默认是灰色)。 24 | 25 | **size** enum('small', 'large') 26 | 27 | 指示器的大小,它是一个枚举类型('small', 'large')。```small```表示指示器的高度是20,```large```表示指示器的高度是36。 28 | -------------------------------------------------------------------------------- /apis/AppRegistry.md: -------------------------------------------------------------------------------- 1 | `AppRegistry` is the JS entry point to running all React Native apps. App root components should register themselves with `AppRegistry.registerComponent`, then the native system can load the bundle for the app and then actually run the app when it's ready by invoking `AppRegistry.runApplication`. 2 | 3 | `AppRegistry` should be `required` early in the `require` sequence to make sure the JS execution environment is setup before other modules are `required`. 4 | 5 | ## Methods 6 | 7 | static **registerConfig**(config: Array) 8 | 9 | static **registerComponent**(appKey: string, getComponentFunc: Function) 10 | 11 | static **registerRunnable**(appKey: string, func: Function) 12 | 13 | static **runApplication**(appKey: string, appParameters: any) -------------------------------------------------------------------------------- /components/TouchableOpacity.md: -------------------------------------------------------------------------------- 1 | A wrapper for making views respond properly to touches. On press down, the opacity of the wrapped view is decreased, dimming it. This is done without actually changing the view hierarchy, and in general is easy to add to an app without weird side-effects. 2 | 3 | Example: 4 | 5 | ```html 6 | renderButton: function() { 7 | return ( 8 | 9 | 13 | 14 | ); 15 | }, 16 | ``` 17 | 18 | ## Props 19 | 20 | [TouchableWithoutFeedback props...](http://facebook.github.io/react-native/docs/touchablewithoutfeedback.html#proptypes) 21 | 22 | **activeOpacity** number 23 | 24 | Determines what the opacity of the wrapped view should be when touch is active. -------------------------------------------------------------------------------- /components/SwitchIOS.md: -------------------------------------------------------------------------------- 1 | Use `SwitchIOS` to render a boolean input on iOS. This is a controlled component, so you must hook in to the `onValueChange` callback and update the `value` prop in order for the component to update, otherwise the user's change will be reverted immediately to reflect `props.value` as the source of truth. 2 | 3 | ## Props 4 | 5 | **disabled** bool 6 | 7 | If true the user won't be able to toggle the switch. Default value is false. 8 | 9 | **onTintColor** string 10 | 11 | Background color when the switch is turned on. 12 | 13 | **onValueChange** function 14 | 15 | Callback that is called when the user toggles the switch. 16 | 17 | **thumbTintColor** string 18 | 19 | Background color for the switch round button. 20 | 21 | **tintColor** string 22 | 23 | Background color when the switch is turned off. 24 | 25 | **value** bool 26 | 27 | The value of the switch, if true the switch will be turned on. Default value is false. -------------------------------------------------------------------------------- /components/SliderIOS.md: -------------------------------------------------------------------------------- 1 | ## Props 2 | 3 | **maximumValue** number 4 | 5 | Initial maximum value of the slider. Default value is 1. 6 | 7 | **minimumValue** number 8 | 9 | Initial minimum value of the slider. Default value is 0. 10 | 11 | **onSlidingComplete** function 12 | 13 | Callback called when the user finishes changing the value (e.g. when the slider is released). 14 | 15 | **onValueChange** function 16 | 17 | Callback continuously called while the user is dragging the slider. 18 | 19 | **style** [View#style](http://facebook.github.io/react-native/docs/view.html#style) 20 | 21 | Used to style and layout the `Slider`. See `StyleSheet.js` and `ViewStylePropTypes.js` for more info. 22 | 23 | **value** number 24 | 25 | Initial value of the slider. The value should be between minimumValue and maximumValue, which default to 0 and 1 respectively. Default value is 0. 26 | 27 | *This is not a controlled component*, e.g. if you don't update the value, the component won't be reset to it's inital value. -------------------------------------------------------------------------------- /apis/StyleSheet.md: -------------------------------------------------------------------------------- 1 | A StyleSheet is an abstraction similar to CSS StyleSheets 2 | 3 | Create a new StyleSheet: 4 | 5 | ```javascript 6 | var styles = StyleSheet.create({ 7 | container: { 8 | borderRadius: 4, 9 | borderWidth: 0.5, 10 | borderColor: '#d6d7da', 11 | }, 12 | title: { 13 | fontSize: 19, 14 | fontWeight: 'bold', 15 | }, 16 | activeTitle: { 17 | color: 'red', 18 | }, 19 | }); 20 | ``` 21 | 22 | Use a StyleSheet: 23 | 24 | ```html 25 | 26 | 27 | 28 | ``` 29 | 30 | Code quality: 31 | 32 | * By moving styles away from the render function, you're making the code code easier to understand. 33 | * Naming the styles is a good way to add meaning to the low level components in the render function. 34 | 35 | Performance: 36 | 37 | * Making a stylesheet from a style object makes it possible to refer to it by ID instead of creating a new style object every time. 38 | * It also allows to send the style only once through the bridge. All subsequent uses are going to refer an id (not implemented yet). 39 | 40 | ## Methods 41 | 42 | static **create**(obj: {[key: string]: any}) -------------------------------------------------------------------------------- /components/TouchableHighlight.md: -------------------------------------------------------------------------------- 1 | A wrapper for making views respond properly to touches. On press down, the opacity of the wrapped view is decreased, which allows the underlay color to show through, darkening or tinting the view. The underlay comes from adding a view to the view hierarchy, which can sometimes cause unwanted visual artifacts if not used correctly, for example if the backgroundColor of the wrapped view isn't explicitly set to an opaque color. 2 | 3 | Example: 4 | 5 | ```html 6 | renderButton: function() { 7 | return ( 8 | 9 | 13 | 14 | ); 15 | }, 16 | ``` 17 | 18 | ## Props 19 | 20 | [**TouchableWithoutFeedback props...**](http://facebook.github.io/react-native/docs/touchablewithoutfeedback.html#proptypes) 21 | 22 | **activeOpacity** number 23 | 24 | Determines what the opacity of the wrapped view should be when touch is active. 25 | 26 | **style** [View#style](http://facebook.github.io/react-native/docs/view.html#style) 27 | 28 | **underlayColor** string 29 | 30 | The color of the underlay that will show through when the touch is active. -------------------------------------------------------------------------------- /polyfills/Flexbox.md: -------------------------------------------------------------------------------- 1 | ## Props 2 | 3 | **alignItems** enum('flex-start', 'flex-end', 'center', 'stretch') 4 | 5 | **alignSelf** enum('auto', 'flex-start', 'flex-end', 'center', 'stretch') 6 | 7 | **borderBottomWidth** number 8 | 9 | **borderLeftWidth** number 10 | 11 | **borderRightWidth** number 12 | 13 | **borderTopWidth** number 14 | 15 | **borderWidth** number 16 | 17 | **bottom** number 18 | 19 | **flex** number 20 | 21 | **flexDirection** enum('row', 'column') 22 | 23 | **flexWrap** enum('wrap', 'nowrap') 24 | 25 | **height** number 26 | 27 | **justifyContent** enum('flex-start', 'flex-end', 'center', 'space-between', 'space-around') 28 | 29 | **left** number 30 | 31 | **margin** number 32 | 33 | **marginBottom** number 34 | 35 | **marginHorizontal** number 36 | 37 | **marginLeft** number 38 | 39 | **marginRight** number 40 | 41 | **marginTop** number 42 | 43 | **marginVertical** number 44 | 45 | **padding** number 46 | 47 | **paddingBottom** number 48 | 49 | **paddingHorizontal** number 50 | 51 | **paddingLeft** number 52 | 53 | **paddingRight** number 54 | 55 | **paddingTop** number 56 | 57 | **paddingVertical** number 58 | 59 | **position** enum('absolute', 'relative') 60 | 61 | **right** number 62 | 63 | **top** number 64 | 65 | **width** number # -------------------------------------------------------------------------------- /apis/VibrationIOS.md: -------------------------------------------------------------------------------- 1 | The Vibration API is exposed at VibrationIOS.vibrate(). On iOS, calling this function will trigger a one second vibration. The vibration is asynchronous so this method will return immediately. 2 | 3 | There will be no effect on devices that do not support Vibration, eg. the iOS simulator. 4 | 5 | Vibration patterns are currently unsupported. 6 | 7 | ## Methods 8 | 9 | static **vibrate**() 10 | 11 | ## Examples 12 | 13 | ```javascript 14 | 'use strict'; 15 | 16 | var React = require('react-native'); 17 | var { 18 | StyleSheet, 19 | View, 20 | Text, 21 | TouchableHighlight, 22 | VibrationIOS 23 | } = React; 24 | 25 | exports.framework = 'React'; 26 | exports.title = 'VibrationIOS'; 27 | exports.description = 'Vibration API for iOS'; 28 | exports.examples = [{ 29 | title: 'VibrationIOS.vibrate()', 30 | render() { 31 | return ( 32 | VibrationIOS.vibrate()}> 35 | 36 | Vibrate 37 | 38 | 39 | ); 40 | }, 41 | }]; 42 | 43 | var styles = StyleSheet.create({ 44 | wrapper: { 45 | borderRadius: 5, 46 | marginBottom: 5, 47 | }, 48 | button: { 49 | backgroundColor: '#eeeeee', 50 | padding: 10, 51 | }, 52 | }); 53 | ``` -------------------------------------------------------------------------------- /components/DatePickerIOS.md: -------------------------------------------------------------------------------- 1 | Use `DatePickerIOS` to render a date/time picker (selector) on iOS. This is a controlled component, so you must hook in to the `onDateChange` callback and update the `date` prop in order for the component to update, otherwise the user's change will be reverted immediately to reflect `props.date` as the source of truth. 2 | 3 | ##Props 4 | **date** Date 5 | 6 | The currently selected date. 7 | 8 | **maximumDate** Date 9 | 10 | Maximum date. 11 | 12 | Restricts the range of possible date/time values. 13 | 14 | **minimumDate** Date 15 | 16 | Minimum date. 17 | 18 | Restricts the range of possible date/time values. 19 | 20 | **minuteInterval** enum(1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30) 21 | 22 | The interval at which minutes can be selected. 23 | 24 | mode enum('date', 'time', 'datetime') 25 | 26 | The date picker mode. 27 | 28 | **onDateChange** function 29 | 30 | Date change handler. 31 | 32 | This is called when the user changes the date or time in the UI. The first and only argument is a Date object representing the new date and time. 33 | 34 | **timeZoneOffsetInMinutes** number 35 | 36 | Timezone offset in minutes. 37 | 38 | By default, the date picker will use the device's timezone. With this parameter, it is possible to force a certain timezone offset. For instance, to show times in Pacific Standard Time, pass -7 * 60. -------------------------------------------------------------------------------- /apis/InteractionManager.md: -------------------------------------------------------------------------------- 1 | InteractionManager allows long-running work to be scheduled after any interactions/animations have completed. In particular, this allows JavaScript animations to run smoothly. 2 | 3 | Applications can schedule tasks to run after interactions with the following: 4 | 5 | ```javascript 6 | InteractionManager.runAfterInteractions(() => { 7 | // ...long-running synchronous task... 8 | }); 9 | ``` 10 | 11 | Compare this to other scheduling alternatives: 12 | 13 | * requestAnimationFrame(): for code that animates a view over time. 14 | * setImmediate/setTimeout(): run code later, note this may delay animations. 15 | * runAfterInteractions(): run code later, without delaying active animations. 16 | 17 | The touch handling system considers one or more active touches to be an 'interaction' and will delay `runAfterInteractions()` callbacks until all touches have ended or been cancelled. 18 | 19 | InteractionManager also allows applications to register animations by creating an interaction 'handle' on animation start, and clearing it upon completion: 20 | 21 | ```javascript 22 | var handle = InteractionManager.createInteractionHandle(); 23 | // run animation... (`runAfterInteractions` tasks are queued) 24 | // later, on animation completion: 25 | InteractionManager.clearInteractionHandle(handle); 26 | // queued tasks run if all handles were cleared 27 | ``` 28 | 29 | ## Methods 30 | static **runAfterInteractions**(callback: Function) 31 | 32 | Schedule a function to run after all interactions have completed. 33 | 34 | static **createInteractionHandle**() 35 | 36 | Notify manager that an interaction has started. 37 | 38 | static **clearInteractionHandle**(handle: number) 39 | 40 | Notify manager that an interaction has completed. -------------------------------------------------------------------------------- /components/TextInput.md: -------------------------------------------------------------------------------- 1 | 基本组件在应用程序中通过键盘输入文本。他的属性有几个特点,比如自动校正,自动大写,提示信息文本,以及不同类型的键盘,如数字键盘。最简单的用例就是使用`TextInput`并订阅`onChangeText`事件来读取用户输入。还有其他事件,如`onSubmitEditing`和`onFocus`可以订阅。A simple example: 2 | 3 | ```html 4 | 5 | this.setState({input: text})} 8 | /> 9 | {'user input: ' + this.state.input} 10 | 11 | ``` 12 | 13 | `value`属性可以用来设置输入的值,设置`value`是设置为TextInput的默认值,但你可以在`onChangeText`事件中持续的改变他。如果你真的想强制TextInput总是还原到你设置的值,可以设置`controlled= {true}`。`multiline`属性不是在所有版本中支持,有些属性是多行的。## 属性 14 | **autoCapitalize** enum('none', 'sentences', 'words', 'characters') 15 | 16 | 他告诉TextInput自动大写某些字符。* characters: 所有字符, 17 | * words: 每一个单词的首字母 18 | * sentences: 每个句子的首字母 (默认) 19 | * none: 不自动大写任何字符 20 | 21 | **autoCorrect** bool 22 | 23 | 如果设置为false,关闭拼写自动更正功能。 默认值是true。 24 | 25 | **autoFocus** bool 26 | 27 | 如果设置为true, 在componentDidMount时激活输入。默认值是false。 28 | 29 | **bufferDelay** number 30 | 31 | 由于JS和原生输入组件存在竞争危害,这个属性有助于避免丢失字符。 32 | 默认值应该是没有问题的,但如果你处理每次按键都需要很长时间,那么你可能需要增大这个值。**clearButtonMode** enum('never', 'while-editing', 'unless-editing', 'always') 33 | 34 | 何时显示清除按钮在文本视图右侧 35 | 36 | **controlled** bool 37 | 38 | 如果你真的希望他是可控制的组件,您可以设置为true,但你可能会看到闪烁现象,丢失按键响应,and/or laggy 输入,这些取决于你如何处理onChange事件。**editable** bool 39 | 40 | 设置为false,文本是不可编辑的。默认值是true。**keyboardType** enum('default', 'numeric') 41 | 42 | 确定要打开的键盘类型,比如数字键盘。**multiline** bool 43 | 44 | 如果为true,文本输入可以是多行的。默认值是假的。**onBlur** function 45 | 46 | 当输入框失去焦点时调用此函数 47 | 48 | **onChangeText** function 49 | 50 | (text: string) => void 51 | 52 | 输入的文本更改时被调用 53 | 54 | **onEndEditing** function 55 | 56 | **onFocus** function 57 | 58 | 当输入框获得焦点时被调用 59 | 60 | 61 | **onSubmitEditing** function 62 | 63 | **placeholder** string 64 | 65 | 能够让你在文本框里显示提示信息,一旦你在文本框里输入了什么信息,提示信息就会隐藏。 66 | 67 | **placeholderTextColor** string 68 | 69 | placeholder文字的颜色 70 | 71 | **selectionState** DocumentSelectionState 72 | 73 | 参考 DocumentSelectionState.js, 这些状态负责维护选中信息 74 | 75 | **style** [Text#style](http://facebook.github.io/react-native/docs/text.html#style) 76 | 77 | **value** string 78 | 79 | 文字框的文字 80 | -------------------------------------------------------------------------------- /polyfills/Network.md: -------------------------------------------------------------------------------- 1 | One of React Native goal is to be a playground where we can experiment with different architectures and crazy ideas. Since browsers are not flexible enough, we had no choice but to reimplement the entire stack. In the places that we did not intend to change, we tried to be as faithful as possible to the browser APIs. The networking stack is a great example. 2 | 3 | ## XMLHttpRequest 4 | 5 | XMLHttpRequest API is implemented on-top of [iOS networking apis](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html). The notable difference from web is the security model: you can read from arbitrary websites on the internet since there is no concept of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing). 6 | 7 | ```javascript 8 | var request = new XMLHttpRequest(); 9 | request.onreadystatechange = (e) => { 10 | if (request.readyState !== 4) { 11 | return; 12 | } 13 | 14 | if (request.status === 200) { 15 | console.log('success', request.responseText); 16 | } else { 17 | console.warn('error'); 18 | } 19 | }; 20 | 21 | request.open('GET', 'https://mywebsite.com/endpoint.php'); 22 | request.send(); 23 | ``` 24 | 25 | Please follow the [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) for a complete description of the API. 26 | 27 | As a developer, you're probably not going to use XMLHttpRequest directly as its API is very tedious to work with. But the fact that it is implemented and compatible with the browser API gives you the ability to use third-party libraries such as [Parse]( https://parse.com/products/javascript) or [super-agent](https://github.com/visionmedia/superagent) directly from npm. 28 | 29 | ## Fetch 30 | 31 | [fetch](https://fetch.spec.whatwg.org/) is a better networking API being worked on by the standard committee and is already available in Chrome. It is available in React Native by default. 32 | 33 | ```javascript 34 | fetch('https://mywebsite.com/endpoint.php') 35 | .then((response) => response.text()) 36 | .then((responseText) => { 37 | console.log(responseText); 38 | }) 39 | .catch((error) => { 40 | console.warn(error); 41 | }); 42 | ``` 43 | -------------------------------------------------------------------------------- /components/MapView.md: -------------------------------------------------------------------------------- 1 | ## Props 2 | 3 | **legalLabelInsets** {top: number, left: number, bottom: number, right: number} 4 | 5 | Insets for the map's legal label, originally at bottom left of the map. See `EdgeInsetsPropType.js` for more information. 6 | 7 | **maxDelta** number 8 | 9 | Maximum size of area that can be displayed. 10 | 11 | **minDelta** number 12 | 13 | Minimum size of area that can be displayed. 14 | 15 | **onRegionChange** function 16 | 17 | Callback that is called continuously when the user is dragging the map. 18 | 19 | **onRegionChangeComplete** function 20 | 21 | Callback that is called once, when the user is done moving the map. 22 | 23 | **pitchEnabled** bool 24 | 25 | When this property is set to `true` and a valid camera is associated with the map, the camera’s pitch angle is used to tilt the plane of the map. When this property is set to `false`, the camera’s pitch angle is ignored and the map is always displayed as if the user is looking straight down onto it. 26 | 27 | region {latitude: number, longitude: number, latitudeDelta: number, longitudeDelta: number} 28 | 29 | The region to be displayed by the map. 30 | 31 | The region is defined by the center coordinates and the span of coordinates to display. 32 | 33 | **rotateEnabled** bool 34 | 35 | When this property is set to `true` and a valid camera is associated with the map, the camera’s heading angle is used to rotate the plane of the map around its center point. When this property is set to `false`, the camera’s heading angle is ignored and the map is always oriented so that true north is situated at the top of the map view 36 | 37 | **scrollEnabled** bool 38 | 39 | If false the user won't be able to change the map region being displayed. Default value is true. 40 | 41 | **showsUserLocation** bool 42 | 43 | If `true` the app will ask for the user's location and focus on it. Default value is false. 44 | 45 | **NOTE**: You need to add NSLocationWhenInUseUsageDescription key in Info.plist to enable geolocation, otherwise it is going to fail silently! 46 | 47 | **style** [View#style](http://facebook.github.io/react-native/docs/view.html#style) 48 | 49 | Used to style and layout the MapView. See `StyleSheet.js` and `ViewStylePropTypes.js` for more info. 50 | 51 | **zoomEnabled** bool 52 | 53 | If `false` the user won't be able to pinch/zoom the map. Default `value` is true. -------------------------------------------------------------------------------- /guides/Debugging.md: -------------------------------------------------------------------------------- 1 | ## Debugging React Native Apps 2 | To debug the javascript code of your react app do the following: 3 | 4 | 1. Run your application in the iOS simulator. 5 | 6 | 2. Press `Command + D` and a webpage should open up at [http://localhost:8081/debugger-ui](http://localhost:8081/debugger-ui). (Chrome only for now) 7 | 8 | 3. Enable [Pause On Caught Exceptions](http://stackoverflow.com/questions/2233339/javascript-is-there-a-way-to-get-chrome-to-break-on-all-errors/17324511#17324511) for a better debugging experience. 9 | 10 | 4. Press `Command + Option + I` to open the Chrome Developer tools, or open it via `View` -> `Developer` -> `Developer Tools`. 11 | 12 | 5. You should now be able to debug as you normally would. 13 | 14 | ## Optional 15 | 16 | Install the [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) extension for Google Chrome. This will allow you to navigate the view hierarchy if you select the `React` tab when the developer tools are open. 17 | 18 | ## Live Reload. 19 | 20 | To activate Live Reload do the following: 21 | 22 | 1. Run your application in the iOS simulator. 23 | 24 | 2. Press `Control + Command + Z`. 25 | 26 | 3. You will now see the `Enable/Disable Live Reload`, `Reload` and `Enable/Disable Debugging` options. 27 | 28 | ## 调试 React Native 应用 29 | 30 | 为了调试你的react app中的javascript代码,你需要做以下事情: 31 | 32 | 1. 在你的ios模拟器中运行你的应用. 33 | 34 | 2. 按下`Command + D`键并且在网页中打开[http://localhost:8081/debugger-ui](http://localhost:8081/debugger-ui)(目前仅限于chrome浏览器中). 35 | 36 | 3. 勾选上[Pause On Caught Exceptions](参见http://stackoverflow.com/questions/2233339/javascript-is-there-a-way-to-get-chrome-to-break-on-all-errors/17324511#17324511)选项,以便更好地进行调试. 37 | 38 | 4. 按下 `Command + Option + I` 组合键打开谷歌浏览器中的开发人员工具, 或者通过`View` -> `Developer` -> `Developer Tools`的方式打开. 39 | 40 | 5. 现在你就可以按照你平时的方式进行调试了. 41 | 42 | ## 可选项 43 | 44 | 在chrome浏览器中安装[React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) 扩展工具. 这样在开发人员工具处于打开状态时如果你选择了'React'选项,就会使得你可以浏览视图的层次. 45 | 46 | ## Live Reload. 47 | 48 | 启动 Live Reload 需要做以下事情: 49 | 50 | 1. 在你的ios模拟器中运行你的应用. 51 | 52 | 2. 按下 `Control + Command + Z` 组合键. 53 | 54 | 3. 现在你就会看到 `Enable/Disable Live Reload`, `Reload` 和 `Enable/Disable Debugging` 选项. 55 | -------------------------------------------------------------------------------- /polyfills/Geolocation.md: -------------------------------------------------------------------------------- 1 | /!\ ATTENTION /!\ You need to add **NSLocationWhenInUseUsageDescription** key in Info.plist to enable geolocation, otherwise it's going to *fail silently*! !/ !/ 2 | 3 | Geolocation follows the MDN specification: [https://developer.mozilla.org/en-US/docs/Web/API/Geolocation](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation) 4 | 5 | ## Methods 6 | 7 | static **getCurrentPosition**(geo_success: Function, geo_error?: Function, geo_options?: Object) 8 | 9 | static **watchPosition**(success: Function, error?: Function, options?: Object) 10 | 11 | static **clearWatch**(watchID: number) 12 | 13 | static **stopObserving**() 14 | 15 | ## Examples 16 | 17 | ```javascript 18 | /* eslint no-console: 0 */ 19 | 'use strict'; 20 | 21 | 22 | var React = require('react-native'); 23 | var { 24 | StyleSheet, 25 | Text, 26 | View, 27 | } = React; 28 | 29 | exports.framework = 'React'; 30 | exports.title = 'Geolocation'; 31 | exports.description = 'Examples of using the Geolocation API.'; 32 | 33 | exports.examples = [ 34 | { 35 | title: 'navigator.geolocation', 36 | render: function(): ReactElement { 37 | return ; 38 | }, 39 | } 40 | ]; 41 | 42 | var GeolocationExample = React.createClass({ 43 | watchID: (null: ?number), 44 | 45 | getInitialState: function() { 46 | return { 47 | initialPosition: 'unknown', 48 | lastPosition: 'unknown', 49 | }; 50 | }, 51 | 52 | componentDidMount: function() { 53 | navigator.geolocation.getCurrentPosition( 54 | (initialPosition) => this.setState({initialPosition}), 55 | (error) => console.error(error) 56 | ); 57 | this.watchID = navigator.geolocation.watchPosition((lastPosition) => { 58 | this.setState({lastPosition}); 59 | }); 60 | }, 61 | 62 | componentWillUnmount: function() { 63 | navigator.geolocation.clearWatch(this.watchID); 64 | }, 65 | 66 | render: function() { 67 | return ( 68 | 69 | 70 | Initial position: 71 | {JSON.stringify(this.state.initialPosition)} 72 | 73 | 74 | Current position: 75 | {JSON.stringify(this.state.lastPosition)} 76 | 77 | 78 | ); 79 | } 80 | }); 81 | 82 | var styles = StyleSheet.create({ 83 | title: { 84 | fontWeight: '500', 85 | }, 86 | }); 87 | ``` -------------------------------------------------------------------------------- /apis/PixelRatio.md: -------------------------------------------------------------------------------- 1 | PixelRatio class gives access to the device pixel density. 2 | 3 | There are a few use cases for using PixelRatio: 4 | 5 | ## Displaying a line that's as thin as the device permits 6 | 7 | A width of 1 is actually pretty thick on an iPhone 4+, we can do one that's thinner using a width of `1 / PixelRatio.get()`. It's a technique that works on all the devices independent of their pixel density. 8 | 9 | ```javascript 10 | style={{ borderWidth: 1 / PixelRatio.get() }} 11 | ``` 12 | 13 | ## Fetching a correctly sized image 14 | 15 | You should get a higher resolution image if you are on a high pixel density device. A good rule of thumb is to multiply the size of the image you display by the pixel ratio. 16 | 17 | ```javascript 18 | var image = getImage({ 19 | width: 200 * PixelRatio.get(), 20 | height: 100 * PixelRatio.get() 21 | }); 22 | 23 | ``` 24 | 25 | ## Methods 26 | 27 | static **get**() 28 | 29 | Returns the device pixel density. Some examples: 30 | 31 | * PixelRatio.get() === 2 32 | - iPhone 4, 4S 33 | - iPhone 5, 5c, 5s 34 | - iPhone 6 35 | * PixelRatio.get() === 3 36 | - iPhone 6 plus 37 | 38 | ## Description 39 | 40 | # Pixel Grid Snapping 41 | 42 | In iOS, you can specify positions and dimensions for elements with arbitrary precision, for example 29.674825. But, ultimately the physical display only have a fixed number of pixels, for example 640×960 for iphone 4 or 750×1334 for iphone 6. iOS tries to be as faithful as possible to the user value by spreading one original pixel into multiple ones to trick the eye. The downside of this technique is that it makes the resulting element look blurry. 43 | 44 | In practice, we found out that developers do not want this feature and they have to work around it by doing manual rounding in order to avoid having blurry elements. In React Native, we are rounding all the pixels automatically. 45 | 46 | We have to be careful when to do this rounding. You never want to work with rounded and unrounded values at the same time as you're going to accumulate rounding errors. Having even one rounding error is deadly because a one pixel border may vanish or be twice as big. 47 | 48 | In React Native, everything in JS and within the layout engine work with arbitrary precision numbers. It's only when we set the position and dimensions of the native element on the main thread that we round. Also, rounding is done relative to the root rather than the parent, again to avoid accumulating rounding errors. -------------------------------------------------------------------------------- /apis/LinkingIOS.md: -------------------------------------------------------------------------------- 1 | `LinkingIOS` gives you a general interface to interact with both, incoming and outgoing app links. 2 | 3 | ## Basic Usage 4 | 5 | ### Handling deep links 6 | 7 | If your app was launched from a external url registered to your app you can access and handle it from any component you want with 8 | 9 | ```javascript 10 | componentDidMount() { 11 | var url = LinkingIOS.popInitialURL(); 12 | } 13 | ``` 14 | 15 | In case you also want to listen to incoming app links during your app's execution you'll need to add the following lines to you `*AppDelegate.m`: 16 | 17 | ```java 18 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 19 | return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; 20 | } 21 | ``` 22 | 23 | And then on your React component you'll be able to listen to the events on LinkingIOS as follows 24 | 25 | ```javascript 26 | componentDidMount() { 27 | LinkingIOS.addEventListener('url', this._handleOpenURL); 28 | }, 29 | componentWillUnmount() { 30 | LinkingIOS.removeEventListener('url', this._handleOpenURL); 31 | }, 32 | _handleOpenURL(event) { 33 | console.log(event.url); 34 | } 35 | ``` 36 | 37 | ### Triggering App links 38 | 39 | To trigger an app link (browser, email or custom schemas) you call 40 | 41 | ```javascript 42 | LinkingIOS.openURL(url) 43 | ``` 44 | 45 | If you want to check if any installed app can handle a given url beforehand you can call 46 | 47 | ```javascript 48 | LinkingIOS.canOpenURL(url, (supported) => { 49 | if (!supported) { 50 | AlertIOS.alert('Can\'t handle url: ' + url); 51 | } else { 52 | LinkingIOS.openURL(url); 53 | } 54 | }); 55 | ``` 56 | 57 | ## Methods 58 | 59 | static **addEventListener**(type: string, handler: Function) 60 | 61 | Add a handler to LinkingIOS changes by listening to the `url` event type and providing the handler 62 | 63 | static **removeEventListener**(type: string, handler: Function) 64 | 65 | Remove a handler by passing the `url` event type and the handler 66 | 67 | static **openURL**(url: string) 68 | 69 | Try to open the given `url` with any of the installed apps. 70 | 71 | static **canOpenURL**(url: string, callback: Function) 72 | 73 | Determine wether or not the an installed app can handle a given `url` The callback function will be called with `bool supported` as the only argument 74 | 75 | static **popInitialURL**() 76 | 77 | If the app launch was triggered by an app link, it will pop the link url, otherwise it will return `null` -------------------------------------------------------------------------------- /components/TabBarIOS.md: -------------------------------------------------------------------------------- 1 | ## Props 2 | style [View#style](http://facebook.github.io/react-native/docs/view.html#style) 3 | 4 | ## Examples 5 | 6 | ```javascript 7 | 'use strict'; 8 | 9 | var React = require('react-native'); 10 | var { 11 | StyleSheet, 12 | TabBarIOS, 13 | Text, 14 | View, 15 | } = React; 16 | 17 | var TabBarExample = React.createClass({ 18 | statics: { 19 | title: '', 20 | description: 'Tab-based navigation.' 21 | }, 22 | 23 | getInitialState: function() { 24 | return { 25 | selectedTab: 'redTab', 26 | notifCount: 0, 27 | presses: 0, 28 | }; 29 | }, 30 | 31 | _renderContent: function(color: string, pageText: string) { 32 | return ( 33 | 34 | {pageText} 35 | {this.state.presses} re-renders of the More tab 36 | 37 | ); 38 | }, 39 | 40 | render: function() { 41 | return ( 42 | 43 | { 47 | this.setState({ 48 | selectedTab: 'blueTab', 49 | }); 50 | }}> 51 | {this._renderContent('#414A8C', 'Blue Tab')} 52 | 53 | 0 ? this.state.notifCount : undefined} 56 | selected={this.state.selectedTab === 'redTab'} 57 | onPress={() => { 58 | this.setState({ 59 | selectedTab: 'redTab', 60 | notifCount: this.state.notifCount + 1, 61 | }); 62 | }}> 63 | {this._renderContent('#783E33', 'Red Tab')} 64 | 65 | { 69 | this.setState({ 70 | selectedTab: 'greenTab', 71 | presses: this.state.presses + 1 72 | }); 73 | }}> 74 | {this._renderContent('#21551C', 'Green Tab')} 75 | 76 | 77 | ); 78 | }, 79 | 80 | }); 81 | 82 | var styles = StyleSheet.create({ 83 | tabContent: { 84 | flex: 1, 85 | alignItems: 'center', 86 | }, 87 | tabText: { 88 | color: 'white', 89 | margin: 50, 90 | }, 91 | }); 92 | 93 | module.exports = TabBarExample; 94 | ``` -------------------------------------------------------------------------------- /quick-start/GettingStarted.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: getting-started 3 | title: Getting Started 4 | layout: docs 5 | category: Quick Start 6 | permalink: docs/getting-started.html 7 | next: tutorial 8 | --- 9 | 10 | ## Requirements 11 | 12 | 1. OS X - This repo only contains the iOS implementation right now, and Xcode only runs on Mac. 13 | 2. New to Xcode? [Download it](https://developer.apple.com/xcode/downloads/) from the Mac App Store. 14 | 3. [Homebrew](http://brew.sh/) is the recommended way to install node, watchman, and flow. 15 | 4. `brew install node`. New to [node](https://nodejs.org/) or [npm](https://docs.npmjs.com/)? 16 | 5. `brew install watchman`. We recommend installing [watchman](https://facebook.github.io/watchman/docs/install.html), otherwise you might hit a node file watching bug. 17 | 6. `brew install flow`. If you want to use [flow](http://www.flowtype.org). 18 | 19 | ## Quick start 20 | 21 | - `npm install -g react-native-cli` 22 | - `react-native init AwesomeProject` 23 | 24 | In the newly created folder `AwesomeProject/` 25 | 26 | - Open `AwesomeProject.xcodeproj` and hit run in Xcode 27 | - Open `index.ios.js` in your text editor of choice and edit some lines 28 | - Hit cmd+R ([twice](http://openradar.appspot.com/19613391)) in your iOS simulator to reload the app and see your change! 29 | 30 | Congratulations! You've just successfully run and modified your first React Native app. 31 | 32 | 33 | # 新手上路 34 | 35 | ## 系统要求 36 | 37 | 1. OS X,目前仅包含了iOS的实现,Xcode只在Mac上才能运行 38 | 2. 开发者可以从Mac应用商店[下载Xcode](https://developer.apple.com/xcode/downloads/) 39 | 3. [Node](https://nodejs.org/)或者[npm](https://docs.npmjs.com/)的新手可以通过`brew install node`来安装Node.js 40 | 4. `brew install watchman`. 我们建议安装[watchman](https://facebook.github.io/watchman/docs/install.html),否则你可能会遇到`node`的文件监控bug 41 | 5. 如果你想使用[flow](http://www.flowtype.org/),可以通过`brew install flow` 42 | 43 | ## 快速上路 44 | 45 | - `npm install -g react-native-cli` 46 | - `react-native init AwesomeProject` 47 | 48 | 在`AwesomeProject/`目录中执行如下操作: 49 | 50 | - 打开`AwesomeProkect.xcodeproj`,然在在`Xcode`中点击`run`运行 51 | - 用文本编辑器打开`index.ios.js`,编辑一些代码 52 | - 在iOS simulator中按cmd + R([twice](http://openradar.appspot.com/19613391))来重载APP,并且观察之前的改动 53 | 54 | 恭喜!您刚刚成功的运行并且编写了您第一个React Native应用。 55 | 56 | ## 备注 57 | 58 | 额外有一步操作在官方文档中没有体现,否则会运行失败。具体如下,两种方式任选一种: 59 | 60 | 打开项目中的`AppDelegate.m` 61 | - 方式一:找到这行代码:jsCodeLocation = [NSURL URLWithString:@"http://`localhost`:8081/index.ios.bundle"],将localhost换成自己的ip 62 | - 方式二: 63 | - 注释掉方式一中的代码 64 | - 去掉`jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];`前面的注释。 65 | - run `npm start` 66 | - run `curl http://localhost:8081/index.ios.bundle -o main.jsbundle` 如果失败的话在后面加上`--ipv4` 67 | - 在XCode中,右击你的项目文件夹,点击`New file`,选择你生成的`main.jsbundle`。 68 | - 推荐第一个方法比较简单。 69 | - 现在就可以在无无服务器的环境下运行你的app拉。 70 | -------------------------------------------------------------------------------- /components/NavigatorIOS.md: -------------------------------------------------------------------------------- 1 | NavigatorIOS wraps UIKit navigation and allows you to add back-swipe functionality across your app. 2 | 3 | ## Routes 4 | 5 | A route is an object used to describe each page in the navigator. The first route is provided to NavigatorIOS as `initialRoute`: 6 | 7 | ```html 8 | render: function() { 9 | return ( 10 | 17 | ); 18 | }, 19 | ``` 20 | 21 | Now MyView will be rendered by the navigator. It will recieve the `route` object in the route prop, a navigator, and all of the props specified in `passProps`. 22 | 23 | See the initialRoute propType for a complete definition of a route. 24 | 25 | ## Navigator 26 | 27 | A `navigator` is an object of navigation functions that a view can call. It is passed as a prop to any component rendered by NavigatorIOS. 28 | 29 | ```javascript 30 | var MyView = React.createClass({ 31 | _handleBackButtonPress: function() { 32 | this.props.navigator.pop(); 33 | }, 34 | _handleNextButtonPress: function() { 35 | this.props.navigator.push(nextRoute); 36 | }, 37 | ... 38 | }); 39 | ``` 40 | 41 | A navigation object contains the following functions: 42 | 43 | * `push(route)` - Navigate forward to a new route 44 | * `pop()` - Go back one page 45 | * `popN(n)` - Go back N pages at once. When N=1, behavior matches pop() 46 | * `replace(route)` - Replace the route for the current page and immediately load the view for the new route 47 | * `replacePrevious(route)` - Replace the route/view for the previous page 48 | * `replacePreviousAndPop(route)` - Replaces the previous route/view and transitions back to it 49 | * `resetTo(route)` - Replaces the top item and popToTop 50 | * `popToRoute(route)` - Go back to the item for a particular route object 51 | * `popToTop()` - Go back to the top item 52 | 53 | Navigator functions are also available on the NavigatorIOS component: 54 | 55 | ```html 56 | var MyView = React.createClass({ 57 | _handleNavigationRequest: function() { 58 | this.refs.nav.push(otherRoute); 59 | }, 60 | render: () => ( 61 | 65 | ), 66 | }); 67 | ``` 68 | 69 | ## Props 70 | 71 | **initialRoute** {component: function, title: string, passProps: object, backButtonTitle: string, rightButtonTitle: string, onRightButtonPress: function, wrapperStyle: [object Object]} 72 | 73 | NavigatorIOS uses "route" objects to identify child views, their props, and navigation bar configuration. "push" and all the other navigation operations expect routes to be like this: 74 | 75 | **itemWrapperStyle** [View#style](http://facebook.github.io/react-native/docs/view.html#style) 76 | 77 | The default wrapper style for components in the navigator. A common use case is to set the backgroundColor for every page 78 | 79 | **tintColor** string 80 | 81 | The color used for buttons in the navigation bar -------------------------------------------------------------------------------- /apis/AlertIOS.md: -------------------------------------------------------------------------------- 1 | AlertIOS manages native iOS alerts, option sheets, and share dialogs 2 | 3 | ## Methods 4 | 5 | static **alert**(title: string, message?: string, buttons?: Array<{ text: ?string; onPress: ?Function; }>) 6 | 7 | ## Examples 8 | 9 | ```javascript 10 | 'use strict'; 11 | 12 | var React = require('react-native'); 13 | var { 14 | StyleSheet, 15 | View, 16 | Text, 17 | TouchableHighlight, 18 | AlertIOS, 19 | } = React; 20 | 21 | exports.framework = 'React'; 22 | exports.title = 'AlertIOS'; 23 | exports.description = 'iOS alerts and action sheets'; 24 | exports.examples = [{ 25 | title: 'Alerts', 26 | render() { 27 | return ( 28 | 29 | AlertIOS.alert( 31 | 'Foo Title', 32 | 'My Alert Msg' 33 | )}> 34 | 35 | Alert with message and default button 36 | 37 | 38 | AlertIOS.alert( 40 | null, 41 | null, 42 | [ 43 | {text: 'Button', onPress: () => console.log('Button Pressed!')}, 44 | ] 45 | )}> 46 | 47 | Alert with only one button 48 | 49 | 50 | AlertIOS.alert( 52 | 'Foo Title', 53 | 'My Alert Msg', 54 | [ 55 | {text: 'Foo', onPress: () => console.log('Foo Pressed!')}, 56 | {text: 'Bar', onPress: () => console.log('Bar Pressed!')}, 57 | ] 58 | )}> 59 | 60 | Alert with two buttons 61 | 62 | 63 | AlertIOS.alert( 65 | 'Foo Title', 66 | null, 67 | [ 68 | {text: 'Foo', onPress: () => console.log('Foo Pressed!')}, 69 | {text: 'Bar', onPress: () => console.log('Bar Pressed!')}, 70 | {text: 'Baz', onPress: () => console.log('Baz Pressed!')}, 71 | ] 72 | )}> 73 | 74 | Alert with 3 buttons 75 | 76 | 77 | AlertIOS.alert( 79 | 'Foo Title', 80 | 'My Alert Msg', 81 | '..............'.split('').map((dot, index) => ({ 82 | text: 'Button ' + index, 83 | onPress: () => console.log('Pressed ' + index) 84 | })) 85 | )}> 86 | 87 | Alert with too many buttons 88 | 89 | 90 | 91 | ); 92 | }, 93 | }]; 94 | 95 | var styles = StyleSheet.create({ 96 | wrapper: { 97 | borderRadius: 5, 98 | marginBottom: 5, 99 | }, 100 | button: { 101 | backgroundColor: '#eeeeee', 102 | padding: 10, 103 | }, 104 | }); 105 | ``` 106 | -------------------------------------------------------------------------------- /apis/StatusBarIOS.md: -------------------------------------------------------------------------------- 1 | All rights reserved. 2 | 3 | This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. 4 | 5 | @flow 6 | 7 | ## Methods 8 | 9 | static **setStyle**(style: number, animated?: boolean) 10 | 11 | static **setHidden**(hidden: boolean, animation: number) 12 | 13 | ## Examples 14 | 15 | ```javascript 16 | 'use strict'; 17 | 18 | var React = require('react-native'); 19 | var { 20 | StyleSheet, 21 | View, 22 | Text, 23 | TouchableHighlight, 24 | StatusBarIOS, 25 | } = React; 26 | 27 | exports.framework = 'React'; 28 | exports.title = 'StatusBarIOS'; 29 | exports.description = 'Module for controlling iOS status bar'; 30 | exports.examples = [{ 31 | title: 'Status Bar Style', 32 | render() { 33 | return ( 34 | 35 | {Object.keys(StatusBarIOS.Style).map((key) => 36 | StatusBarIOS.setStyle(StatusBarIOS.Style[key])}> 38 | 39 | setStyle(StatusBarIOS.Style.{key}) 40 | 41 | 42 | )} 43 | 44 | ); 45 | }, 46 | }, { 47 | title: 'Status Bar Style Animated', 48 | render() { 49 | return ( 50 | 51 | {Object.keys(StatusBarIOS.Style).map((key) => 52 | StatusBarIOS.setStyle(StatusBarIOS.Style[key], true)}> 54 | 55 | setStyle(StatusBarIOS.Style.{key}, true) 56 | 57 | 58 | )} 59 | 60 | ); 61 | }, 62 | }, { 63 | title: 'Status Bar Hidden', 64 | render() { 65 | return ( 66 | 67 | {Object.keys(StatusBarIOS.Animation).map((key) => 68 | 69 | StatusBarIOS.setHidden(true, StatusBarIOS.Animation[key])}> 71 | 72 | setHidden(true, StatusBarIOS.Animation.{key}) 73 | 74 | 75 | StatusBarIOS.setHidden(false, StatusBarIOS.Animation[key])}> 77 | 78 | setHidden(false, StatusBarIOS.Animation.{key}) 79 | 80 | 81 | 82 | )} 83 | 84 | ); 85 | }, 86 | }]; 87 | 88 | var styles = StyleSheet.create({ 89 | wrapper: { 90 | borderRadius: 5, 91 | marginBottom: 5, 92 | }, 93 | button: { 94 | backgroundColor: '#eeeeee', 95 | padding: 10, 96 | }, 97 | }); 98 | ``` 99 | 100 | 版权所有 101 | 102 | This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. 103 | 104 | 这里的所有代码都遵循源码树的根目录下的LICENSE文件中的BSD协议。追加的专利授权可以在相同目录的PATENTS文件中找到。 105 | 106 | @flow 107 | 108 | ## Methods 109 | 110 | static **setStyle**(style: number, animated?: boolean) 111 | 112 | 设置IOS状态栏的样式。 113 | 114 | static **setHidden**(hidden: boolean, animation: number) 115 | 116 | 设置IOS状态栏的西安隐状态。 117 | -------------------------------------------------------------------------------- /guides/LinkingLibraries.md: -------------------------------------------------------------------------------- 1 | Not every app uses all the native capabilities, and including the code to support all those features would impact in the binary size... But we still want to make easy to add these features whenever you need them. 2 | 3 | 不是所有的应用都需要全部的原生功能,同时包含支持所有特性的代码将会影响二进制文件的大小...但是我们仍然希望当需要这些特性的时候可以方便地使用它们。 4 | 5 | With that in mind we exposed many of these features as independent static libraries. 6 | 7 | 出于这个考虑,我们暴露大多数特性作为独立的静态库。 8 | 9 | For most of the libs it will be as simples as dragging two files, sometimes a third step will be necessary, but no more than that. 10 | 11 | *All the libraries we ship with React Native live on the Libraries folder in the root of the repository. Some of them are pure JavaScript, and you just need to require it. Other libraries also rely on some native code, in that case you'll have to add these files to your app, otherwise the app will throw an error as soon as you try to use the library.*Linking Libraries 12 | 13 | 对于大部分的库,这个操作像拖动两个文件一样简单,有时第三步是必需的,但仅此而已。 14 | 15 | *我们发布的 React Native的库都在根目录下的Libraries文件夹中。其中一部分是原生JavaScript,你只需直接调用它。其他库依赖于原生代码,在这种情况下你需要添加这类文件到你的应用中,否则在应用中使用这些库的时候将会抛出异常。* 16 | 17 | ## Here the few steps to link your libraries that contain native code 18 | 19 | ##连接含有原生代码库的步骤 20 | 21 | ### Step 1 22 | ### 第一步 23 | 24 | 25 | If the library has native code, there must be a .xcodeproj file inside it's folder. Drag this file to your project on Xcode (usually under the Libaries group on Xcode); 26 | 27 | 如果某个库有原生代码,必须有一个以**. xcodeproj**为拓展名的文件在文件夹中。在Xcode中拖动这个文件到你的项目中(通常在Xcode的Libraries分组) 28 |
29 | 30 |
31 | 32 | ### Step 2 33 | 34 | Click on your main project file (the one that represents the .xcodeproj) select Build Phases and drag the static library from the Products folder insed the Library you are importing to Link Binary With Libraries 35 | 36 |
37 | 38 |
39 | 40 | ###第二步 41 | 42 | 点击你的主项目文件(以**.xcodeproj**结尾)选择**Build Phases**,将**Libraries** 里面的 **Products**文件夹中的静态文件拖动到**Link Binary With Libraries**这一栏。 43 | 44 | ### Step 3 45 | Not every library will need this step, what you need to consider is: 46 | 47 | *Do I need to know the contents of the library at compile time?* 48 | 49 | ###第三步 50 | 不是每个库都需要这步,你需要确认这个: 51 | 52 | *在编译期间,是否需要知道这些库的内容?* 53 | 54 | What that means is, are you using this library on the native site or just in JavaScript? If you are just using it in JavaScript, you are good to go! 55 | 56 | This step is not necessary for all libraries that we ship we React Native but `PushNotificationIOS` and `LinkingIOS`. 57 | 58 | In the case of the `PushNotificationIOS` for example, you have to call a method on the library from your `AppDelegate` every time a new push notifiation is received. 59 | 60 | For that we need to know the library's headers. To achieve that you have to go to your project's file, select `Build Settings` and search for `Header Search Paths`. There you should include the path to you library (if it has relevant files on subdirectories remember to make it `recursive`, like `React` on the example). 61 | 62 | 你是在原生环境还是JavaScript使用这个库?如果只是在JavaScript中使用这个库,你无需往下看。 63 | 64 | 这一步在发布的React Native所有库中,除了`PushNotificationIOS `和`LinkingIOS `,都不是必需的。 65 | 66 | 在`PushNotificationIOS `的示例中,每一个新推送通知被接收时,必须从 `AppDelegate `中调用库的方法。 67 | 68 | 因此我们需要知道库的`headers`,进入项目文件,选择`Build Settings`,找到`Header Search Paths`,填写库的路径。(如果在子目录中含有相关文件,记住选中`recursive `,如示例中的`React `)。 69 | 70 |
71 | 72 |
73 | 74 | -------------------------------------------------------------------------------- /components/View.md: -------------------------------------------------------------------------------- 1 | The most fundamental component for building UI, `View` is a container that supports layout with flexbox, style, some touch handling, and accessibility controls, and is designed to be nested inside other views and to have 0 to many children of any type. `View` maps directly to the native view equivalent on whatever platform react is running on, whether that is a `UIView`, `
`, `android.view`, etc. This example creates a `View` that wraps two colored boxes and custom component in a row with padding. 2 | 3 | ```html 4 | 5 | 6 | 7 | 8 | 9 | ``` 10 | 11 | `Views` are designed to be used with `StyleSheets` for clarity and performance, although inline styles are also supported. 12 | 13 | ## Props 14 | 15 | **accessibilityLabel** string 16 | 17 | Overrides the text that's read by the screen reader when the user interacts with the element. By default, the label is constructed by traversing all the children and accumulating all the Text nodes separated by space. 18 | 19 | **accessible** bool 20 | 21 | When true, indicates that the view is an accessibility element. By default, all the touchable elements are accessible. 22 | 23 | **onMoveShouldSetResponder** function 24 | 25 | For most touch interactions, you'll simply want to wrap your component in `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`, `ScrollResponder.js` and `ResponderEventPlugin.js` for more discussion. 26 | 27 | **onResponderGrant** function 28 | 29 | **onResponderMove** function 30 | 31 | **onResponderReject** function 32 | 33 | **onResponderRelease** function 34 | 35 | **onResponderTerminate** function 36 | 37 | **onResponderTerminationRequest** function 38 | 39 | **onStartShouldSetResponder** function 40 | 41 | **onStartShouldSetResponderCapture** function 42 | 43 | **pointerEvents** enum('box-none', 'none', 'box-only', 'auto') 44 | 45 | In the absence of auto property, none is much like `CSS`'s `none` value. `box-none` is as if you had applied the `CSS` class: 46 | 47 | ```css 48 | .box-none { 49 | pointer-events: none; 50 | } 51 | .box-none * { 52 | pointer-events: all; 53 | } 54 | ``` 55 | 56 | `box-only` is the equivalent of 57 | 58 | ```csss 59 | .box-only { 60 | pointer-events: all; 61 | } 62 | .box-only * { 63 | pointer-events: none; 64 | } 65 | ``` 66 | 67 | But since `pointerEvents` does not affect layout/appearance, and we are already deviating from the spec by adding additional modes, we opt to not include `pointerEvents` on `style`. On some platforms, we would need to implement it as a `className` anyways. Using `style` or not is an implementation detail of the platform. 68 | 69 | **removeClippedSubviews** bool 70 | 71 | This is a special performance property exposed by RCTView and is useful for scrolling content when there are many subviews, most of which are offscreen. For this property to be effective, it must be applied to a view that contains many subviews that extend outside its bound. The subviews must also have overflow: hidden, as should the containing view (or one of its superviews). 72 | 73 | style style 74 | 75 | ├─[**Flexbox...**](http://facebook.github.io/react-native/docs/flexbox.html#proptypes) 76 | ├─**backgroundColor** string 77 | ├─**borderBottomColor** string 78 | ├─**borderColor** string 79 | ├─**borderLeftColor** string 80 | ├─**borderRadius** number 81 | ├─**borderRightColor** string 82 | ├─**borderTopColor** string 83 | ├─**opacity** number 84 | ├─**overflow** enum('visible', 'hidden') 85 | ├─**rotation** number 86 | ├─**scaleX** number 87 | ├─**scaleY** number 88 | ├─**shadowColor** string 89 | ├─**shadowOffset** {h: number, w: number} 90 | ├─**shadowOpacity** number 91 | ├─**shadowRadius** number 92 | ├─**transformMatrix** [number] 93 | ├─**translateX** number 94 | └─**translateY** number 95 | 96 | **testID** string 97 | 98 | Used to locate this view in end-to-end tests. -------------------------------------------------------------------------------- /apis/AppStateIOS.md: -------------------------------------------------------------------------------- 1 | `AppStateIOS` can tell you if the app is in the foreground or background, and notify you when the state changes. 2 | 3 | `AppStateIOS` is frequently used to determine the intent and proper behavior when handling push notifications. 4 | 5 | ## iOS App States 6 | 7 | * `active` - The app is running in the foreground 8 | * `background` - The app is running in the background. The user is either in another app or on the home screen 9 | * `inactive` - This is a transition state that currently never happens for typical React Native apps. 10 | 11 | For more information, see [Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html) 12 | 13 | ## Basic Usage 14 | 15 | To see the current state, you can check AppStateIOS.currentState, which will be kept up-to-date. However, currentState will be null at launch while AppStateIOS retrieves it over the bridge. 16 | 17 | ```javascript 18 | getInitialState: function() { 19 | return { 20 | currentAppState: AppStateIOS.currentState, 21 | }; 22 | }, 23 | componentDidMount: function() { 24 | AppStateIOS.addEventListener('change', this._handleAppStateChange); 25 | }, 26 | componentWillUnmount: function() { 27 | AppStateIOS.removeEventListener('change', this._handleAppStateChange); 28 | }, 29 | _handleAppStateChange: function(currentAppState) { 30 | this.setState({ currentAppState, }); 31 | }, 32 | render: function() { 33 | return ( 34 | Current state is: {this.state.currentAppState} 35 | ); 36 | }, 37 | ``` 38 | 39 | This example will only ever appear to say "Current state is: active" because the app is only visible to the user when in the `active` state, and the null state will happen only momentarily. 40 | 41 | ## Methods 42 | 43 | static **addEventListener**(type: string, handler: Function) 44 | 45 | Add a handler to AppState changes by listening to the change event type and providing the handler 46 | 47 | static **removeEventListener**(type: string, handler: Function) 48 | 49 | Remove a handler by passing the change event type and the handler 50 | 51 | ## Examples 52 | 53 | ```javascript 54 | 'use strict'; 55 | 56 | var React = require('react-native'); 57 | var { 58 | AppStateIOS, 59 | Text, 60 | View 61 | } = React; 62 | 63 | var AppStateSubscription = React.createClass({ 64 | getInitialState() { 65 | return { 66 | appState: AppStateIOS.currentState, 67 | previousAppStates: [], 68 | }; 69 | }, 70 | componentDidMount: function() { 71 | AppStateIOS.addEventListener('change', this._handleAppStateChange); 72 | }, 73 | componentWillUnmount: function() { 74 | AppStateIOS.removeEventListener('change', this._handleAppStateChange); 75 | }, 76 | _handleAppStateChange: function(appState) { 77 | var previousAppStates = this.state.previousAppStates.slice(); 78 | previousAppStates.push(this.state.appState); 79 | this.setState({ 80 | appState, 81 | previousAppStates, 82 | }); 83 | }, 84 | render() { 85 | if (this.props.showCurrentOnly) { 86 | return ( 87 | 88 | {this.state.appState} 89 | 90 | ); 91 | } 92 | return ( 93 | 94 | {JSON.stringify(this.state.previousAppStates)} 95 | 96 | ); 97 | } 98 | }); 99 | 100 | exports.title = 'AppStateIOS'; 101 | exports.description = 'iOS app background status'; 102 | exports.examples = [ 103 | { 104 | title: 'AppStateIOS.currentState', 105 | description: 'Can be null on app initialization', 106 | render() { return {AppStateIOS.currentState}; } 107 | }, 108 | { 109 | title: 'Subscribed AppStateIOS:', 110 | description: 'This changes according to the current state, so you can only ever see it rendered as "active"', 111 | render(): ReactElement { return ; } 112 | }, 113 | { 114 | title: 'Previous states:', 115 | render(): ReactElement { return ; } 116 | }, 117 | ]; 118 | ``` -------------------------------------------------------------------------------- /apis/CameraRoll.md: -------------------------------------------------------------------------------- 1 | All rights reserved. 2 | 3 | This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. 4 | 5 | @flow 6 | 7 | ## Methods 8 | 9 | static **saveImageWithTag**(tag: string, successCallback, errorCallback) 10 | 11 | Saves the image with tag `tag` to the camera roll. 12 | 13 | @param {string} tag - Can be any of the three kinds of tags we accept: 1. URL 2. assets-library tag 3. tag returned from storing an image in memory 14 | 15 | static **getPhotos**(params: object, callback: function, errorCallback: function) 16 | 17 | Invokes `callback` with photo identifier objects from the local camera roll of the device matching shape defined by `getPhotosReturnChecker`. 18 | 19 | @param {object} params - See `getPhotosParamChecker`. @param {function} callback - Invoked with arg of shape defined by `getPhotosReturnChecker` on success. @param {function} errorCallback - Invoked with error message on error. 20 | 21 | ## Examples 22 | 23 | ```javascript 24 | 'use strict'; 25 | 26 | var React = require('react-native'); 27 | var { 28 | CameraRoll, 29 | Image, 30 | SliderIOS, 31 | StyleSheet, 32 | SwitchIOS, 33 | Text, 34 | View, 35 | } = React; 36 | 37 | var CameraRollView = require('./CameraRollView.ios'); 38 | 39 | var CAMERA_ROLL_VIEW = 'camera_roll_view'; 40 | 41 | var CameraRollExample = React.createClass({ 42 | 43 | getInitialState() { 44 | return { 45 | groupTypes: 'SavedPhotos', 46 | sliderValue: 1, 47 | bigImages: true, 48 | }; 49 | }, 50 | 51 | render() { 52 | return ( 53 | 54 | 57 | {(this.state.bigImages ? 'Big' : 'Small') + ' Images'} 58 | 62 | {'Group Type: ' + this.state.groupTypes} 63 | 69 | 70 | ); 71 | }, 72 | 73 | _renderImage(asset) { 74 | var imageSize = this.state.bigImages ? 150 : 75; 75 | var imageStyle = [styles.image, {width: imageSize, height: imageSize}]; 76 | var location = asset.node.location.longitude ? 77 | JSON.stringify(asset.node.location) : 'Unknown location'; 78 | return ( 79 | 80 | 84 | 85 | {asset.node.image.uri} 86 | {location} 87 | {asset.node.group_name} 88 | {new Date(asset.node.timestamp).toString()} 89 | 90 | 91 | ); 92 | }, 93 | 94 | _onSliderChange(value) { 95 | var options = CameraRoll.GroupTypesOptions; 96 | var index = Math.floor(value * options.length * 0.99); 97 | var groupTypes = options[index]; 98 | if (groupTypes !== this.state.groupTypes) { 99 | this.setState({groupTypes: groupTypes}); 100 | } 101 | }, 102 | 103 | _onSwitchChange(value) { 104 | this.refs[CAMERA_ROLL_VIEW].rendererChanged(); 105 | this.setState({ bigImages: value }); 106 | } 107 | }); 108 | 109 | var styles = StyleSheet.create({ 110 | row: { 111 | flexDirection: 'row', 112 | flex: 1, 113 | }, 114 | url: { 115 | fontSize: 9, 116 | marginBottom: 14, 117 | }, 118 | image: { 119 | margin: 4, 120 | }, 121 | info: { 122 | flex: 1, 123 | }, 124 | }); 125 | 126 | exports.title = ''; 127 | exports.description = 'Example component that uses CameraRoll to list user\'s photos'; 128 | exports.examples = [ 129 | { 130 | title: 'Photos', 131 | render(): ReactElement { return ; } 132 | } 133 | ]; 134 | ``` -------------------------------------------------------------------------------- /components/ListView.md: -------------------------------------------------------------------------------- 1 | ListView - A core component designed for efficient display of vertically scrolling lists of changing data. The minimal API is to create a `ListView.DataSource`, populate it with a simple array of data blobs, and instantiate a `ListView` component with that data source and a `renderRow` callback which takes a blob from the data array and returns a renderable component. 2 | 3 | Minimal example: 4 | 5 | ```html 6 | getInitialState: function() { 7 | var ds = new ListViewDataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 8 | return { 9 | dataSource: ds.cloneWithRows(['row 1', 'row 2']), 10 | }; 11 | }, 12 | 13 | render: function() { 14 | return ( 15 | {rowData}} 18 | /> 19 | ); 20 | }, 21 | ``` 22 | 23 | ListView also supports more advanced features, including sections with sticky section headers, header and footer support, callbacks on reaching the end of the available data (`onEndReached`) and on the set of rows that are visible in the device viewport change (`onChangeVisibleRows`), and several performance optimizations. 24 | 25 | There are a few performance operations designed to make ListView scroll smoothly while dynamically loading potentially very large (or conceptually infinite) data sets: 26 | 27 | * Only re-render changed rows - the hasRowChanged function provided to the data source tells the ListView if it needs to re-render a row because the source data has changed - see ListViewDataSource for more details. 28 | 29 | * Rate-limited row rendering - By default, only one row is rendered per event-loop (customizable with the `pageSize` prop). This breaks up the work into smaller chunks to reduce the chance of dropping frames while rendering rows. 30 | 31 | ##Props 32 | 33 | [**ScrollView props...**](http://facebook.github.io/react-native/docs/scrollview.html#proptypes) 34 | 35 | **dataSource** ListViewDataSource 36 | 37 | **initialListSize** number 38 | 39 | How many rows to render on initial component mount. Use this to make it so that the first screen worth of data apears at one time instead of over the course of multiple frames. 40 | 41 | **onChangeVisibleRows** function 42 | 43 | (visibleRows, changedRows) => void 44 | 45 | Called when the set of visible rows changes. `visibleRows` maps { sectionID: { rowID: true }} for all the visible rows, and `changedRows` maps { sectionID: { rowID: true | false }} for the rows that have changed their visibility, with true indicating visible, and false indicating the view has moved out of view. 46 | 47 | **onEndReached** function 48 | 49 | Called when all rows have been rendered and the list has been scrolled to within `onEndReachedThreshold` of the bottom. The native scroll event is provided. 50 | 51 | **onEndReachedThreshold** number 52 | 53 | Threshold in pixels for onEndReached. 54 | 55 | **pageSize** number 56 | 57 | Number of rows to render per event loop. 58 | 59 | **removeClippedSubviews** bool 60 | 61 | An experimental performance optimization for improving scroll perf of large lists, used in conjunction with `overflow: 'hidden'` on the row containers. Use at your own risk. 62 | 63 | **renderFooter** function 64 | 65 | () => renderable 66 | 67 | The header and footer are always rendered (if these props are provided) on every render pass. If they are expensive to re-render, wrap them in StaticContainer or other mechanism as appropriate. Footer is always at the bottom of the list, and header at the top, on every render pass. 68 | 69 | **renderHeader** function 70 | 71 | **renderRow** function 72 | 73 | (rowData, sectionID, rowID) => renderable Takes a data entry from the data source and its ids and should return a renderable component to be rendered as the row. By default the data is exactly what was put into the data source, but it's also possible to provide custom extractors. 74 | 75 | **renderSectionHeader** function 76 | 77 | (sectionData, sectionID) => renderable 78 | 79 | If provided, a sticky header is rendered for this section. The sticky behavior means that it will scroll with the content at the top of the section until it reaches the top of the screen, at which point it will stick to the top until it is pushed off the screen by the next section header. 80 | 81 | **scrollRenderAheadDistance** number 82 | 83 | How early to start rendering rows before they come on screen, in pixels. -------------------------------------------------------------------------------- /apis/PanResponder.md: -------------------------------------------------------------------------------- 1 | `PanResponder` reconciles several touches into a single gesture. It makes single-touch gestures resilient to extra touches, and can be used to recognize simple multi-touch gestures. 2 | 3 | It provides a predictable wrapper of the responder handlers provided by the [gesture responder system](http://facebook.github.io/react-native/docs/gesture-responder-system.html). For each handler, it provides a new `gestureState` object alongside the normal event. 4 | 5 | A `gestureState` object has the following: 6 | 7 | * `stateID` - ID of the gestureState- persisted as long as there at least one touch on screen 8 | * `moveX` - the latest screen coordinates of the recently-moved touch 9 | * `moveY` - the latest screen coordinates of the recently-moved touch 10 | * `x0` - the screen coordinates of the responder grant 11 | * `y0` - the screen coordinates of the responder grant 12 | * `dx` - accumulated distance of the gesture since the touch started 13 | * `dy` - accumulated distance of the gesture since the touch started 14 | * `vx` - current velocity of the gesture 15 | * `vy` - current velocity of the gesture 16 | * `numberActiveTouches` - Number of touches currently on screeen 17 | 18 | ## Basic Usage 19 | 20 | ```javascript 21 | componentWillMount: function() { 22 | this._panGesture = PanResponder.create({ 23 | // Ask to be the responder: 24 | onStartShouldSetPanResponder: (evt, gestureState) => true, 25 | onStartShouldSetPanResponderCapture: (evt, gestureState) => true, 26 | onMoveShouldSetPanResponder: (evt, gestureState) => true, 27 | onMoveShouldSetPanResponderCapture: (evt, gestureState) => true, 28 | 29 | onPanResponderGrant: (evt, gestureState) => { 30 | // The guesture has started. Show visual feedback so the user knows 31 | // what is happening! 32 | 33 | // gestureState.{x,y}0 will be set to zero now 34 | }, 35 | onPanResponderMove: (evt, gestureState) => { 36 | // The most recent move distance is gestureState.move{X,Y} 37 | 38 | // The accumulated gesture distance since becoming responder is 39 | // gestureState.d{x,y} 40 | }, 41 | onResponderTerminationRequest: (evt, gestureState) => true, 42 | onPanResponderRelease: (evt, gestureState) => { 43 | // The user has released all touches while this view is the 44 | // responder. This typically means a gesture has succeeded 45 | }, 46 | onPanResponderTerminate: (evt, gestureState) => { 47 | // Another component has become the responder, so this gesture 48 | // should be cancelled 49 | }, 50 | }); 51 | }, 52 | 53 | render: function() { 54 | return ( 55 | 56 | ); 57 | }, 58 | ``` 59 | 60 | ## Working Example 61 | 62 | To see it in action, try the [PanResponder example in UIExplorer](https://github.com/facebook/react-native/blob/master/Examples/UIExplorer/ResponderExample.js) 63 | 64 | ## Methods 65 | 66 | static **create**(config: object) 67 | 68 | @param {object} config Enhanced versions of all of the responder callbacks that provide not only the typical `ResponderSyntheticEvent`, but also the `PanResponder` gesture state. Simply replace the word Responder with `PanResponder` in each of the typical `onResponder*` callbacks. For example, the config object would look like: 69 | 70 | * `onMoveShouldSetPanResponder: (e, gestureState) => {...}` 71 | * `onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}` 72 | * `onStartShouldSetPanResponder: (e, gestureState) => {...}` 73 | * `onStartShouldSetPanResponderCapture: (e, gestureState) => {...}` 74 | * `onPanResponderReject: (e, gestureState) => {...}` 75 | * `onPanResponderGrant: (e, gestureState) => {...}` 76 | * `onPanResponderStart: (e, gestureState) => {...}` 77 | * `onPanResponderEnd: (e, gestureState) => {...}` 78 | * `onPanResponderRelease: (e, gestureState) => {...}` 79 | * `onPanResponderMove: (e, gestureState) => {...}` 80 | * `onPanResponderTerminate: (e, gestureState) => {...}` 81 | * `onPanResponderTerminationRequest: (e, gestureState) => {...}` 82 | 83 | In general, for events that have capture equivalents, we update the gestureState once in the capture phase and can use it in the bubble phase as well. 84 | 85 | Be careful with onStartShould* callbacks. They only reflect updated `gestureState` for start/end events that bubble/capture to the Node. Once the node is the responder, you can rely on every start/end event being processed by the gesture and `gestureState` being updated accordingly. (numberActiveTouches) may not be totally accurate unless you are the responder. -------------------------------------------------------------------------------- /components/Navigator.md: -------------------------------------------------------------------------------- 1 | Use `Navigator` to transition between different scenes in your app. To accomplish this, provide route objects to the navigator to identify each scene, and also a `renderScene` function that the navigator can use to render the scene for a given route. 2 | 3 | To change the animation or gesture properties of the scene, provide a `configureScene` prop to get the config object for a given route. See `Navigator.SceneConfigs` for default animations and more info on scene config options. 4 | 5 | ## Basic Usage 6 | 7 | ```html 8 | 11 | { 14 | var nextIndex = route.index + 1; 15 | navigator.push({ 16 | name: 'Scene ' + nextIndex, 17 | index: nextIndex, 18 | }); 19 | }} 20 | onBack={() => { 21 | if (route.index > 0) { 22 | navigator.pop(); 23 | } 24 | }} 25 | /> 26 | } 27 | /> 28 | ``` 29 | 30 | ## Navigation Methods 31 | `Navigator` can be told to navigate in two ways. If you have a ref to the element, you can invoke several methods on it to trigger navigation: 32 | 33 | * `jumpBack()` - Jump backward without unmounting the current scene 34 | * `jumpForward()` - Jump forward to the next scene in the route stack 35 | * `jumpTo(route)` - Transition to an existing scene without unmounting 36 | * `push(route)` - Navigate forward to a new scene, squashing any scenes that you could jumpForward to 37 | * `pop()` - Transition back and unmount the current scene 38 | * `replace(route)` - Replace the current scene with a new route 39 | * `replaceAtIndex(route, index)` - Replace a scene as specified by an index 40 | * `replacePrevious(route)` - Replace the previous scene 41 | * `immediatelyResetRouteStack(routeStack)` - Reset every scene with an array of routes 42 | * `popToRoute(route)` - Pop to a particular scene, as specified by it's route. All scenes after it will be unmounted 43 | * `popToTop()` - Pop to the first scene in the stack, unmounting every other scene 44 | 45 | ## Navigator Object 46 | 47 | The navigator object is made available to scenes through the `renderScene` function. The object has all of the navigation methods on it, as well as a few utilities: 48 | 49 | * `parentNavigator` - a refrence to the parent navigator object that was passed in through props.navigator 50 | * `onWillFocus` - used to pass a navigation focus event up to the parent navigator 51 | * `onDidFocus` - used to pass a navigation focus event up to the parent navigator 52 | 53 | ## Props 54 | 55 | **configureScene** function 56 | 57 | Optional function that allows configuration about scene animations and gestures. Will be invoked with the route and should return a scene configuration object 58 | 59 | ```javascript 60 | (route) => Navigator.SceneConfigs.FloatFromRight 61 | ``` 62 | 63 | **initialRoute** object 64 | 65 | Provide a single "route" to start on. A route is an arbitrary object that the navigator will use to identify each scene before rendering. Either initialRoute or initialRouteStack is required. 66 | 67 | **initialRouteStack** [object] 68 | 69 | Provide a set of routes to initially mount the scenes for. Required if no initialRoute is provided 70 | 71 | **navigationBar** node 72 | 73 | Optionally provide a navigation bar that persists across scene transitions 74 | 75 | **navigator** object 76 | 77 | Optionally provide the navigator object from a parent Navigator 78 | 79 | **onDidFocus** function 80 | 81 | Will be called with the new route of each scene after the transition is complete or after the initial mounting. This overrides the onDidFocus handler that would be found in this.props.navigator 82 | 83 | **onItemRef** function 84 | 85 | Will be called with (ref, indexInStack) when the scene ref changes 86 | 87 | **onWillFocus** function 88 | 89 | Will emit the target route upon mounting and before each nav transition, overriding the handler in this.props.navigator. This overrides the onDidFocus handler that would be found in this.props.navigator 90 | 91 | **renderScene** function 92 | 93 | Required function which renders the scene for a given route. Will be invoked with the route, the navigator object, and a ref handler that will allow a ref to your scene to be provided by props.onItemRef 94 | 95 | ```javascript 96 | (route, navigator, onRef) => 97 | 98 | ``` 99 | 100 | **sceneStyle** [View#style](http://facebook.github.io/react-native/docs/view.html#style) 101 | 102 | Styles to apply to the container of each scene 103 | 104 | **shouldJumpOnBackstackPop** bool 105 | 106 | Should the backstack back button "jump" back instead of pop? Set to true if a jump forward might happen after the android back button is pressed, so the scenes will remain mounted -------------------------------------------------------------------------------- /components/ScrollView.md: -------------------------------------------------------------------------------- 1 | Component that wraps platform ScrollView while providing integration with touch locking "responder" system. 2 | 3 | Doesn't yet support other contained responders from blocking this scroll view from becoming the responder. 4 | 5 | ## Props 6 | 7 | **alwaysBounceHorizontal** bool 8 | 9 | When true, the scroll view bounces horizontally when it reaches the end even if the content is smaller than the scroll view itself. The default value is true when `horizontal={true}` and false otherwise. 10 | 11 | **alwaysBounceVertical** bool 12 | 13 | When true, the scroll view bounces vertically when it reaches the end even if the content is smaller than the scroll view itself. The default value is false when `horizontal={true}` and true otherwise. 14 | 15 | **automaticallyAdjustContentInsets** bool 16 | 17 | **centerContent** bool 18 | 19 | When true, the scroll view automatically centers the content when the content is smaller than the scroll view bounds; when the content is larger than the scroll view, this property has no effect. The default value is false. 20 | 21 | **contentContainerStyle** StyleSheetPropType(ViewStylePropTypes) 22 | 23 | These styles will be applied to the scroll view content container which wraps all of the child views. Example: 24 | 25 | return ( ); ... var styles = StyleSheet.create({ contentContainer: { paddingVertical: 20 } }); 26 | 27 | **contentInset** {top: number, left: number, bottom: number, right: number} 28 | 29 | **contentOffset** PointPropType 30 | 31 | **decelerationRate** number 32 | 33 | A floating-point number that determines how quickly the scroll view decelerates after the user lifts their finger. Reasonable choices include - Normal: 0.998 (the default) - Fast: 0.9 34 | 35 | **horizontal** bool 36 | 37 | When true, the scroll view's children are arranged horizontally in a row instead of vertically in a column. The default value is false. 38 | 39 | **keyboardDismissMode** enum("none", 'interactive', 'onDrag') 40 | 41 | Determines whether the keyboard gets dismissed in response to a drag. - 'none' (the default), drags do not dismiss the keyboard. - 'onDrag', the keyboard is dismissed when a drag begins. - 'interactive', the keyboard is dismissed interactively with the drag and moves in synchrony with the touch; dragging upwards cancels the dismissal. 42 | 43 | **keyboardShouldPersistTaps** bool 44 | 45 | When false, tapping outside of the focused text input when the keyboard is up dismisses the keyboard. When true, the scroll view will not catch taps, and the keyboard will not dismiss automatically. The default value is false. 46 | 47 | **maximumZoomScale** number 48 | 49 | The maximum allowed zoom scale. The default value is 1.0. 50 | 51 | **minimumZoomScale** number 52 | 53 | The minimum allowed zoom scale. The default value is 1.0. 54 | 55 | **onScroll** function 56 | 57 | **onScrollAnimationEnd** function 58 | 59 | **pagingEnabled** bool 60 | 61 | When true, the scroll view stops on multiples of the scroll view's size when scrolling. This can be used for horizontal pagination. The default value is false. 62 | 63 | **removeClippedSubviews** bool 64 | 65 | Experimental: When true, offscreen child views (whose `overflow` value is `hidden`) are removed from their native backing superview when offscreen. This canimprove scrolling performance on long lists. The default value is false. 66 | 67 | **scrollEnabled** bool 68 | 69 | scrollIndicatorInsets {top: number, left: number, bottom: number, right: number} 70 | 71 | **scrollsToTop** bool 72 | 73 | When true, the scroll view scrolls to top when the status bar is tapped. The default value is true. 74 | 75 | **showsHorizontalScrollIndicator** bool 76 | 77 | **showsVerticalScrollIndicator** bool 78 | 79 | **stickyHeaderIndices** [number] 80 | 81 | An array of child indices determining which children get docked to the top of the screen when scrolling. For example, passing `stickyHeaderIndices={[0]}` will cause the first child to be fixed to the top of the scroll view. This property is not supported in conjunction with `horizontal={true}`. 82 | 83 | **style** style 84 | 85 | ├─[**Flexbox...**](http://facebook.github.io/react-native/docs/flexbox.html#proptypes) 86 | ├─**backgroundColor** string 87 | ├─**borderBottomColor** string 88 | ├─**borderColor** string 89 | ├─**borderLeftColor** string 90 | ├─**borderRadius** number 91 | ├─**borderRightColor** string 92 | ├─**borderTopColor** string 93 | ├─**opacity** number 94 | ├─**overflow** enum('visible', 'hidden') 95 | ├─**rotation** number 96 | ├─**scaleX** number 97 | ├─**scaleY** number 98 | ├─**shadowColor** string 99 | ├─**shadowOffset** {h: number, w: number} 100 | ├─**shadowOpacity** number 101 | ├─**shadowRadius** number 102 | ├─**transformMatrix** [number] 103 | ├─**translateX** number 104 | └─**translateY** number 105 | 106 | **throttleScrollCallbackMS** number 107 | 108 | **zoomScale** number 109 | 110 | The current scale of the scroll view content. The default value is 1.0. -------------------------------------------------------------------------------- /apis/NetInfo.md: -------------------------------------------------------------------------------- 1 | NetInfo exposes info about online/offline status 2 | 3 | ## reachabilityIOS 4 | 5 | Asyncronously determine if the device is online and on a cellular network. 6 | 7 | * `none` - device is offline 8 | * `wifi` - device is online and connected via wifi, or is the iOS simulator 9 | * `cell` - device is connected via Edge, 3G, WiMax, or LTE 10 | * `unknown` - error case and the network status is unknown 11 | 12 | ```javascript 13 | NetInfo.reachabilityIOS.fetch().done((reach) => { 14 | console.log('Initial: ' + reach); 15 | }); 16 | function handleFirstReachabilityChange(reach) { 17 | console.log('First change: ' + reach); 18 | NetInfo.reachabilityIOS.removeEventListener( 19 | 'change', 20 | handleFirstReachabilityChange 21 | ); 22 | } 23 | NetInfo.reachabilityIOS.addEventListener( 24 | 'change', 25 | handleFirstReachabilityChange 26 | ); 27 | ``` 28 | 29 | ## isConnected 30 | 31 | Available on all platforms. Asyncronously fetch a boolean to determine internet connectivity. 32 | 33 | ```javascript 34 | NetInfo.isConnected.fetch().done((isConnected) => { 35 | console.log('First, is ' + (isConnected ? 'online' : 'offline')); 36 | }); 37 | function handleFirstConnectivityChange(isConnected) { 38 | console.log('Then, is ' + (isConnected ? 'online' : 'offline')); 39 | NetInfo.isConnected.removeEventListener( 40 | 'change', 41 | handleFirstConnectivityChange 42 | ); 43 | } 44 | NetInfo.isConnected.addEventListener( 45 | 'change', 46 | handleFirstConnectivityChange 47 | ); 48 | ``` 49 | 50 | ## Examples 51 | 52 | ```javascript 53 | 'use strict'; 54 | 55 | var React = require('react-native'); 56 | var { 57 | NetInfo, 58 | Text, 59 | View 60 | } = React; 61 | 62 | var ReachabilitySubscription = React.createClass({ 63 | getInitialState() { 64 | return { 65 | reachabilityHistory: [], 66 | }; 67 | }, 68 | componentDidMount: function() { 69 | NetInfo.reachabilityIOS.addEventListener( 70 | 'change', 71 | this._handleReachabilityChange 72 | ); 73 | }, 74 | componentWillUnmount: function() { 75 | NetInfo.reachabilityIOS.removeEventListener( 76 | 'change', 77 | this._handleReachabilityChange 78 | ); 79 | }, 80 | _handleReachabilityChange: function(reachability) { 81 | var reachabilityHistory = this.state.reachabilityHistory.slice(); 82 | reachabilityHistory.push(reachability); 83 | this.setState({ 84 | reachabilityHistory, 85 | }); 86 | }, 87 | render() { 88 | return ( 89 | 90 | {JSON.stringify(this.state.reachabilityHistory)} 91 | 92 | ); 93 | } 94 | }); 95 | 96 | var ReachabilityCurrent = React.createClass({ 97 | getInitialState() { 98 | return { 99 | reachability: null, 100 | }; 101 | }, 102 | componentDidMount: function() { 103 | NetInfo.reachabilityIOS.addEventListener( 104 | 'change', 105 | this._handleReachabilityChange 106 | ); 107 | NetInfo.reachabilityIOS.fetch().done( 108 | (reachability) => { this.setState({reachability}); } 109 | ); 110 | }, 111 | componentWillUnmount: function() { 112 | NetInfo.reachabilityIOS.removeEventListener( 113 | 'change', 114 | this._handleReachabilityChange 115 | ); 116 | }, 117 | _handleReachabilityChange: function(reachability) { 118 | this.setState({ 119 | reachability, 120 | }); 121 | }, 122 | render() { 123 | return ( 124 | 125 | {this.state.reachability} 126 | 127 | ); 128 | } 129 | }); 130 | 131 | var IsConnected = React.createClass({ 132 | getInitialState() { 133 | return { 134 | isConnected: null, 135 | }; 136 | }, 137 | componentDidMount: function() { 138 | NetInfo.isConnected.addEventListener( 139 | 'change', 140 | this._handleConnectivityChange 141 | ); 142 | NetInfo.isConnected.fetch().done( 143 | (isConnected) => { this.setState({isConnected}); } 144 | ); 145 | }, 146 | componentWillUnmount: function() { 147 | NetInfo.isConnected.removeEventListener( 148 | 'change', 149 | this._handleConnectivityChange 150 | ); 151 | }, 152 | _handleConnectivityChange: function(isConnected) { 153 | this.setState({ 154 | isConnected, 155 | }); 156 | }, 157 | render() { 158 | return ( 159 | 160 | {this.state.isConnected ? 'Online' : 'Offline'} 161 | 162 | ); 163 | } 164 | }); 165 | 166 | exports.title = 'NetInfo'; 167 | exports.description = 'Monitor network status'; 168 | exports.examples = [ 169 | { 170 | title: 'NetInfo.isConnected', 171 | description: 'Asyncronously load and observe connectivity', 172 | render(): ReactElement { return ; } 173 | }, 174 | { 175 | title: 'NetInfo.reachabilityIOS', 176 | description: 'Asyncronously load and observe iOS reachability', 177 | render(): ReactElement { return ; } 178 | }, 179 | { 180 | title: 'NetInfo.reachabilityIOS', 181 | description: 'Observed updates to iOS reachability', 182 | render(): ReactElement { return ; } 183 | }, 184 | ]; 185 | ``` -------------------------------------------------------------------------------- /guides/Testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: testing 3 | title: Testing 4 | layout: docs 5 | category: Guides 6 | permalink: docs/testing.html 7 | next: activityindicatorios 8 | --- 9 | 10 | ## Running Tests and Contributing 11 | 12 | The React Native repo has several tests you can run to verify you haven't caused a regression with your PR. These tests are run with the [Travis](http://docs.travis-ci.com/) continuous integration system, and will automatically post the results to your PR. You can also run them locally with cmd+U in the IntegrationTest and UIExplorer apps in Xcode. You can run the jest tests via `npm test` on the command line. We don't have great test coverage yet, however, so most changes will still require significant manual verification, but we would love it if you want to help us increase our test coverage! 13 | 14 | ## Jest Tests 15 | 16 | [Jest](http://facebook.github.io/jest/) tests are JS-only tests run on the command line with node. The tests themselves live in the `__tests__` directories of the files they test, and there is a large emphasis on aggressively mocking out functionality that is not under test for failure isolation and maximum speed. You can run the existing React Native jest tests with `npm test` from the react-native root, and we encourage you to add your own tests for any components you want to contribute to. See [`getImageSource-test.js`](https://github.com/facebook/react-native/blob/master/Examples/Movies/__tests__/getImageSource-test.js) for a basic example. 17 | 18 | ## Integration Tests. 19 | 20 | React Native provides facilities to make it easier to test integrated components that require both native and JS components to communicate across the bridge. The two main components are `RCTTestRunner` and `RCTTestModule`. `RCTTestRunner` sets up the ReactNative environment and provides facilities to run the tests as `XCTestCase`s in Xcode (`runTest:module` is the simplest method). `RCTTestModule` is exported to JS via `NativeModules` as `TestModule`. The tests themselves are written in JS, and must call `TestModule.markTestCompleted()` when they are done, otherwise the test will timeout and fail. Test failures are primarily indicated by throwing an exception. It is also possible to test error conditions with `runTest:module:initialProps:expectErrorRegex:` or `runTest:module:initialProps:expectErrorBlock:` which will expect an error to be thrown and verify the error matches the provided criteria. See [`IntegrationTestHarnessTest.js`](https://github.com/facebook/react-native/blob/master/IntegrationTests/IntegrationTestHarnessTest.js) and [`IntegrationTestsTests.m`](https://github.com/facebook/react-native/blob/master/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m) for example usage. 21 | 22 | ## Snapshot Tests 23 | 24 | A common type of integration test is the snapshot test. These tests render a component, and verify snapshots of the screen against reference images using `TestModule.verifySnapshot()`, using the [`FBSnapshotTestCase`](https://github.com/facebook/ios-snapshot-test-case) library behind the scenes. Reference images are recorded by setting `recordMode = YES` on the `RCTTestRunner`, then running the tests. Snapshots will differ slightly between 32 and 64 bit, and various OS versions, so it's recommended that you enforce tests are run with the correct configuration. It's also highly recommended that all network data be mocked out, along with other potentially troublesome dependencies. See [`SimpleSnapshotTest`](https://github.com/facebook/react-native/blob/master/IntegrationTests/SimpleSnapshotTest.js) for a basic example. 25 | 26 | ## 运行测试和贡献代码 27 | 28 | React Native 仓库已经有一些测试用例了,你可以自行验证你发起的 PR 还能保证项目能正常回归。这些测试用例运行在[Travis](http://docs.travis-ci.com/)持续集成系统上,针对你的 PR 会自动将运行结果发布到 CI 上。你也可以本地在 Xcode 里使用 IntegrationTest 和 UIExplorer 应用,通过按 cmd+U 快捷键来回归这些测试用例。当然,你也可以命令行下使用 `npm test` 来运行 jest 测试用例。当前,测试用例覆盖率并不好,因此,对于目前大部分代码变化,仍然需要人工进行仔细地验证回归。当然,如果你乐意帮助我们增加测试用例的覆盖率,我们将会非常欢迎! 29 | 30 | ## Jest 测试 31 | 32 | [Jest](http://facebook.github.io/jest/) 测试用例目前只是 JS 的测试用例,使用 node 在命令行下运行。测试用例文件放在它所要测试的文件所在文件夹下的 `__tests__` 文件夹里,有大量被模拟的功能并没有被测试,由于失败隔离和最大速度的缘故。你可以在 react-native 根目录下使用 `npm test` 命令运行已经存在的 React Native jest 测试用例,我们鼓励大家为你要贡献的任何组件添加你自己的测试用例。具体你可以查看这个基本的例子[`getImageSource-test.js`](https://github.com/facebook/react-native/blob/master/Examples/Movies/__tests__/getImageSource-test.js)。 33 | 34 | ## 集成测试 35 | 36 | React Native 提供了一些基础设施,使得你可以很方便地测试集成组件,这要求你的本地组件和 JS 组件能够通过桥接方式进行通信。其中的两个主要组件是 `RCTTestRunner` 和 `RCTTestModule` 。`RCTTestRunner` 建立了 ReactNative 环境并提供一些工具方法使得测试用例能作为 Xcode 里 `XCTestCase` 测试用例来运行(`runTest:module` 是最简单的方法)。`RCTTestModule` 是通过 `NativeModules` 作为 `TestModule` 暴露给 JS 的。测试用例本身是通过 JS 写的,当测试用例执行完成必须调用 `TestModule.markTestCompleted()` 方法,否则会因为超时而导致测试用例失败。测试失败,通常主要通过抛异常来体现。你也可能需要通过使用 `runTest:module:initialProps:expectErrorRegex:` 或 `runTest:module:initialProps:expectErrorBlock:` 来测试错误条件,这时候它会期望抛出一个错误,并通过匹配给定的条件来验证错误。具体使用,你可以参考例子[`IntegrationTestHarnessTest.js`](https://github.com/facebook/react-native/blob/master/IntegrationTests/IntegrationTestHarnessTest.js) 和 [`IntegrationTestsTests.m`](https://github.com/facebook/react-native/blob/master/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m)。 37 | 38 | 39 | ## 快照测试 40 | 41 | 一种公共类型的集成测试是快照测试。这些测试用例会渲染一个组件,并使用 `TestModule.verifySnapshot()` 方法来对比参考图像来验证屏幕的快照,该测试场景背后使用了 [`FBSnapshotTestCase`](https://github.com/facebook/ios-snapshot-test-case) 库。参考图像的录制,是通过在 `RCTTestRunner` 设置 `recordMode = YES`,然后运行测试用例。快照在32位和62位操作系统下有明显不同,以及在各种操作系统版本下,因此推荐你强制让所有测试用例在准确的配置下运行。同时也极力推荐你对所有网络数据进行模拟,以及其它潜在可能比较麻烦的依赖。具体使用例子,可以参考[`SimpleSnapshotTest`](https://github.com/facebook/react-native/blob/master/IntegrationTests/SimpleSnapshotTest.js)。 42 | 43 | -------------------------------------------------------------------------------- /polyfills/Timers.md: -------------------------------------------------------------------------------- 1 | Timers are an important part of an application and React Native implements the [browser timers](https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Timers). 2 | 3 | ## Timers 4 | 5 | - setTimeout, clearTimeout 6 | - setInterval, clearInterval 7 | - setImmediate, clearImmediate 8 | - requestAnimationFrame, cancelAnimationFrame 9 | 10 | `requestAnimationFrame(fn)` is the exact equivalent of `setTimeout(fn, 0)`, they are triggered right after the screen has been flushed. 11 | 12 | `setImmediate` is executed at the end of the current JavaScript execution block, right before sending the batched response back to native. Note that if you call `setImmediate` within a `setImmediate` callback, it will be executed right away, it won't yield back to native in between. 13 | 14 | The `Promise` implementation uses `setImmediate` as its asynchronicity primitive. 15 | 16 | 17 | ## InteractionManager 18 | 19 | One reason why well-built native apps feel so smooth is by avoiding expensive operations during interactions and animations. In React Native, we currently have a limitation that there is only a single JS execution thread, but you can use `InteractionManager` to make sure long-running work is scheduled to start after any interactions/animations have completed. 20 | 21 | Applications can schedule tasks to run after interactions with the following: 22 | 23 | ```javascript 24 | InteractionManager.runAfterInteractions(() => { 25 | // ...long-running synchronous task... 26 | }); 27 | ``` 28 | 29 | Compare this to other scheduling alternatives: 30 | 31 | - requestAnimationFrame(): for code that animates a view over time. 32 | - setImmediate/setTimeout/setInterval(): run code later, note this may delay animations. 33 | - runAfterInteractions(): run code later, without delaying active animations. 34 | 35 | The touch handling system considers one or more active touches to be an 'interaction' and will delay `runAfterInteractions()` callbacks until all touches have ended or been cancelled. 36 | 37 | InteractionManager also allows applications to register animations by creating an interaction 'handle' on animation start, and clearing it upon completion: 38 | 39 | ```javascript 40 | var handle = InteractionManager.createInteractionHandle(); 41 | // run animation... (`runAfterInteractions` tasks are queued) 42 | // later, on animation completion: 43 | InteractionManager.clearInteractionHandle(handle); 44 | // queued tasks run if all handles were cleared 45 | ``` 46 | 47 | 48 | ## TimerMixin 49 | 50 | We found out that the primary cause of fatals in apps created with React Native was due to timers firing after a component was unmounted. To solve this recurring issue, we introduced `TimerMixin`. If you include `TimerMixin`, then you can replace your calls to `setTimeout(fn, 500)` with `this.setTimeout(fn, 500)` (just prepend `this.`) and everything will be properly cleaned up for you when the component unmounts. 51 | 52 | ```javascript 53 | var TimerMixin = require('react-timer-mixin'); 54 | 55 | var Component = React.createClass({ 56 | mixins: [TimerMixin], 57 | componentDidMount: function() { 58 | this.setTimeout( 59 | () => { console.log('I do not leak!'); }, 60 | 500 61 | ); 62 | } 63 | }); 64 | ``` 65 | 66 | We highly recommend never using bare timers and always using this mixin, it will save you from a lot of hard to track down bugs. 67 | 68 | 定时器是应用程序的重要组成部分.React Native遵循浏览器版本相关规则实现定时器[浏览器定时器参考](https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Timers). 69 | 70 | ## 定时器 71 | 72 | - setTimeout, clearTimeout 73 | - setInterval, clearInterval 74 | - setImmediate, clearImmediate 75 | - requestAnimationFrame, cancelAnimationFrame 76 | 77 | `requestAnimationFrame(fn)` 与`setTimeout(fn, 0)`调用效果相同, 二者均在屏幕刷新后立刻触发. 78 | 79 | `setImmediate`在当前Javascript代码运行完毕, 与原生线程通信之前执行.请注意,如果你在setImmediate函数的回调函数中调用了setImmediate,那么回调中的setImmediate将立即执行,此过程不与原生线程通信. 80 | 81 | `Promise`对象,就是利用`setImmediate` 作为基础,实现ES6 Promise/A+的同步机制. 82 | 83 | ## InteractionManager对象 84 | 85 | 设计良好的原生App之所以能够运行平滑,原因在于在动画和交互操作进行时,系统禁止了开销大的指令运行.在React Native中,我们做了限制,程序中时刻只有一个JS运行线程(JavaScript Core VM),但是你可以通过使用InteractionManager对象来保证一个需要长时间执行的任务,在交互或动画运行完成后开始执行. 86 | 87 | 程序可以预先计划某项任务在交互完成后执行: 88 | 89 | ```javascript 90 | InteractionManager.runAfterInteractions(() => { 91 | // ...需要长时间运行的同步任务... 92 | }); 93 | ``` 94 | 95 | 比较互动管理器与其他代码计划运行调用方式: 96 | - requestAnimationFrame() 控制一个视图实现一段动画 97 | - setImmediate/setTimeout/setInterval(): 延迟运行计划运行的代码,请注意,这种调用方式会阻塞动画运行. 98 | - runAfterInteractions(): 延迟运行计划运行的代码,不会阻塞正在运行的动画 99 | 100 | 当屏幕上有一个或更多触点时,触点管理系统会认为当前存在交互,在触点全部消失时自动调用`runAfterInteractions()` 回调函数. 101 | 102 | 我们也可以通过InteractionManager对象的createInteractionHanle()注册动画,实现动画串联播放 103 | 104 | ```javascript 105 | var handle = InteractionManager.createInteractionHandle(); 106 | // 运行一段动画... (`runAfterInteractions` 中注册的函数目前在队列中) 107 | // 在动画完成时: 108 | InteractionManager.clearInteractionHandle(handle); 109 | // 在所有createInteractionHandle注册的方法完成后,runAfterInteractions注册的任务开始运行 110 | ``` 111 | 112 | ## 定时器成员(TimerMixin) 113 | 114 | 通过React Native创建的应用的大部分运行错误源于定时器在组件卸载后触发.为了解决这个问题,React Native引入了定时器成员(TimerMixin)概念.引入定时器成员后,代码中可以使用有归属对象的定时器'this.setTimeout(fn, 500)'代替掉无归属对象的定时器'setTimeout(fn, 500)',这样做的好处是当组件卸载时,会自动清理掉定时器,避免出现定时器在卸载后依旧能触发的问题. 115 | 116 | ```javascript 117 | var TimerMixin = require('react-timer-mixin'); 118 | var Component = React.createClass({ 119 | mixins: [TimerMixin], 120 | componentDidMount: function() { 121 | this.setTimeout( 122 | () => { console.log('I do not leak!'); }, 123 | 500 124 | ); 125 | } 126 | }); 127 | ``` 128 | 129 | 在此强烈建议您不要使用无归属对象的定时器,转而使用定时器成员,这样做能有效规避BUG. 130 | -------------------------------------------------------------------------------- /guides/Style.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: style 3 | title: Style 4 | layout: docs 5 | category: Guides 6 | permalink: docs/style.html 7 | next: gesture-responder-system 8 | --- 9 | 10 | React Native doesn't implement CSS but instead relies on JavaScript to let you style your application. This has been a controversial decision and you can read through those slides for the rationale behind it. 11 | 12 | 13 | 14 | ## Declare Styles 15 | 16 | The way to declare styles in React Native is the following: 17 | 18 | ```javascript 19 | var styles = StyleSheet.create({ 20 | base: { 21 | width: 38, 22 | height: 38, 23 | }, 24 | background: { 25 | backgroundColor: '#222222', 26 | }, 27 | active: { 28 | borderWidth: 2, 29 | borderColor: '#00ff00', 30 | }, 31 | }); 32 | ``` 33 | 34 | `StyleSheet.create` construct is optional but provides some key advantages. It ensures that the values are **immutable** and **opaque** by transforming them into plain numbers that reference an internal table. By putting it at the end of the file, you also ensure that they are only created once for the application and not on every render. 35 | 36 | All the attribute names and values are a subset of what works on the web. For layout, React Native implements [Flexbox](/react-native/docs/flexbox.html). 37 | 38 | ## Using Styles 39 | 40 | All the core components accept a style attribute 41 | 42 | ```javascript 43 | 44 | 45 | ``` 46 | 47 | and also accepts an array of styles 48 | 49 | ```javascript 50 | 51 | ``` 52 | 53 | The behavior is the same as `Object.assign`: in case of conflicting values, the one from the right-most element will have precedence and falsy values like `false`, `undefined` and `null` will be ignored. A common pattern is to conditionally add a style based on some condition. 54 | 55 | ```javascript 56 | 57 | ``` 58 | 59 | Finally, if you really have to, you can also create style objects in render, but they are highly discouraged. Put them last in the array definition. 60 | 61 | ```javascript 62 | 68 | ``` 69 | 70 | ## Pass Styles Around 71 | 72 | In order to let a call site customize the style of your component children, you can pass styles around. Use `View.propTypes.style` and `Text.propTypes.style` in order to make sure only styles are being passed. 73 | 74 | ```javascript 75 | var List = React.createClass({ 76 | propTypes: { 77 | style: View.propTypes.style, 78 | elementStyle: View.propTypes.style, 79 | }, 80 | render: function() { 81 | return ( 82 | 83 | {elements.map((element) => 84 | 85 | )} 86 | 87 | ); 88 | } 89 | }); 90 | 91 | // ... in another file ... 92 | 93 | ``` 94 | 95 | React Native并没有实现CSS,但是替代地依赖于javascript从而让你可以对你的应用进行自定义样式. 这是一个具有争议性的决定并且你可以通过实现它背后原理的幻灯片来阅读它. 96 | 97 | 98 | 99 | ## 声明样式 100 | 101 | 在 React Native 中 声明样式的方法如下所示: 102 | 103 | ```javascript 104 | var styles = StyleSheet.create({ 105 | base: { 106 | width: 38, 107 | height: 38, 108 | }, 109 | background: { 110 | backgroundColor: '#222222', 111 | }, 112 | active: { 113 | borderWidth: 2, 114 | borderColor: '#00ff00', 115 | }, 116 | }); 117 | ``` 118 | 119 | `StyleSheet.create` 构造函数是可选的,但是它具有许多关键性的优势. 它通过把值转化为参考内部表中的普通数字从而使得那些值是和 **不可改变** and **透明的** . 通过将它放置到文件的末尾处, 你也可以保证他们在你的应用中仅仅创建一次并且不需要每次都渲染. 120 | 121 | 所有的属性名和属性值都是web应用中运行的一部分. 至于布局, React Native 实现了 [Flexbox](/react-native/docs/flexbox.html). 122 | 123 | ## 使用样式 124 | 125 | 所有的核心组件都接受一个样式属性. 126 | 127 | ```javascript 128 | 129 | 130 | ``` 131 | 132 | 并且也接受一个样式列表的数组 133 | 134 | ```javascript 135 | 136 | ``` 137 | 138 | 它的行为和`Object.assign`如出一辙: 为了防止值出现冲突, 最右边的元素具有最高的优先级并且像 `false`, `undefined` 和 `null` 这样非法的值将会被忽略. 一种普遍的模式就是基于一些条件条件性地增加样式. 139 | 140 | ```javascript 141 | 142 | ``` 143 | 144 | 最后, 如果你非要这么做, 你也可以在渲染的时候创建一个样式对象, 但是并不鼓励这样做. 最好的方式是将他们在数组定义时放在最后. 145 | 146 | ```javascript 147 | 153 | ``` 154 | 155 | ## 分发样式 156 | 157 | 为了能够让一个访问站点定制你的子样式组件,你可以对你的样式进行分发. 为了确保你的样式能够被分发,你可以使用 `View.propTypes.style` 和 `Text.propTypes.style` . 158 | 159 | ```javascript 160 | var List = React.createClass({ 161 | propTypes: { 162 | style: View.propTypes.style, 163 | elementStyle: View.propTypes.style, 164 | }, 165 | render: function() { 166 | return ( 167 | 168 | {elements.map((element) => 169 | 170 | )} 171 | 172 | ); 173 | } 174 | }); 175 | 176 | // ... in another file ... 177 | 178 | ``` 179 | -------------------------------------------------------------------------------- /apis/AsyncStorage.md: -------------------------------------------------------------------------------- 1 | AsyncStorage is a simple, asynchronous, persistent, global, key-value storage system. It should be used instead of LocalStorage. 2 | 3 | It is recommended that you use an abstraction on top of AsyncStorage instead of AsyncStorage directly for anything more than light usage since it operates globally. 4 | 5 | This JS code is a simple facad over the native iOS implementation to provide a clear JS API, real Error objects, and simple non-multi functions. 6 | 7 | ## Methods 8 | 9 | static **getItem**(key: string, callback: (error: ?Error, result: ?string) => void) 10 | 11 | Fetches `key` and passes the result to `callback`, along with an `Error` if there is any. 12 | 13 | static **setItem**(key: string, value: string, callback: ?(error: ?Error) => void) 14 | 15 | Sets `value` for `key` and calls `callback` on completion, along with an `Error` if there is any. 16 | 17 | static **removeItem**(key: string, callback: ?(error: ?Error) => void) 18 | 19 | static **mergeItem**(key: string, value: string, callback: ?(error: ?Error) => void) 20 | 21 | Merges existing value with input value, assuming they are stringified json. 22 | 23 | Not supported by all native implementations. 24 | 25 | static **clear**(callback: ?(error: ?Error) => void) 26 | 27 | Erases *all* AsyncStorage for all clients, libraries, etc. You probably don't want to call this - use removeItem or multiRemove to clear only your own keys instead. 28 | 29 | static **getAllKeys**(callback: (error: ?Error) => void) 30 | 31 | Gets *all* keys known to the system, for all callers, libraries, etc. 32 | 33 | static **multiGet**(keys: Array, callback: (errors: ?Array, result: ?Array>) => void) 34 | 35 | multiGet invokes callback with an array of key-value pair arrays that matches the input format of multiSet. 36 | 37 | multiGet(['k1', 'k2'], cb) -> cb([['k1', 'val1'], ['k2', 'val2']]) 38 | 39 | static **multiSet**(keyValuePairs: Array>, callback: ?(errors: ?Array) => void) 40 | 41 | multiSet and multiMerge take arrays of key-value array pairs that match the output of multiGet, e.g. 42 | 43 | multiSet([['k1', 'val1'], ['k2', 'val2']], cb); 44 | 45 | static **multiRemove**(keys: Array, callback: ?(errors: ?Array) => void) 46 | 47 | Delete all the keys in the `keys` array. 48 | 49 | static **multiMerge**(keyValuePairs: Array>, callback: ?(errors: ?Array) => void) 50 | 51 | Merges existing values with input values, assuming they are stringified json. 52 | 53 | Not supported by all native implementations. 54 | 55 | ## Examples 56 | 57 | ```javascript 58 | 'use strict'; 59 | 60 | var React = require('react-native'); 61 | var { 62 | AsyncStorage, 63 | PickerIOS, 64 | Text, 65 | View 66 | } = React; 67 | var PickerItemIOS = PickerIOS.Item; 68 | 69 | var STORAGE_KEY = '@AsyncStorageExample:key'; 70 | var COLORS = ['red', 'orange', 'yellow', 'green', 'blue']; 71 | 72 | var BasicStorageExample = React.createClass({ 73 | componentDidMount() { 74 | AsyncStorage.getItem(STORAGE_KEY, (error, value) => { 75 | if (error) { 76 | this._appendMessage('AsyncStorage error: ' + error.message); 77 | } else if (value !== null) { 78 | this.setState({selectedValue: value}); 79 | this._appendMessage('Recovered selection from disk: ' + value); 80 | } else { 81 | this._appendMessage('Initialized with no selection on disk.'); 82 | } 83 | }); 84 | }, 85 | getInitialState() { 86 | return { 87 | selectedValue: COLORS[0], 88 | messages: [], 89 | }; 90 | }, 91 | 92 | render() { 93 | var color = this.state.selectedValue; 94 | return ( 95 | 96 | 99 | {COLORS.map((value) => ( 100 | 105 | ))} 106 | 107 | 108 | {'Selected: '} 109 | 110 | {this.state.selectedValue} 111 | 112 | 113 | {' '} 114 | 115 | Press here to remove from storage. 116 | 117 | {' '} 118 | Messages: 119 | {this.state.messages.map((m) => {m})} 120 | 121 | ); 122 | }, 123 | 124 | _onValueChange(selectedValue) { 125 | this.setState({selectedValue}); 126 | AsyncStorage.setItem(STORAGE_KEY, selectedValue, (error) => { 127 | if (error) { 128 | this._appendMessage('AsyncStorage error: ' + error.message); 129 | } else { 130 | this._appendMessage('Saved selection to disk: ' + selectedValue); 131 | } 132 | }); 133 | }, 134 | 135 | _removeStorage() { 136 | AsyncStorage.removeItem(STORAGE_KEY, (error) => { 137 | if (error) { 138 | this._appendMessage('AsyncStorage error: ' + error.message); 139 | } else { 140 | this._appendMessage('Selection removed from disk.'); 141 | } 142 | }); 143 | }, 144 | 145 | _appendMessage(message) { 146 | this.setState({messages: this.state.messages.concat(message)}); 147 | }, 148 | }); 149 | 150 | exports.title = 'AsyncStorage'; 151 | exports.description = 'Asynchronous local disk storage.'; 152 | exports.examples = [ 153 | { 154 | title: 'Basics - getItem, setItem, removeItem', 155 | render(): ReactElement { return ; } 156 | }, 157 | ]; 158 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native 文档翻译计划 2 | ## EFE Team 3 | ## 翻译流程 4 | 5 | * issue中领取任务 6 | * 在working分支中完成翻译 7 | * commit上要带上#issueID关联到issue 8 | * issue中@ diysimon,通知review 9 | * 确认后merge到master分支 10 | 11 | ## 翻译进度shangwu 12 | ### QUICK START 13 | |章节|翻译状态|英文文档是否完整|负责人| 14 | |----|----|----|------| 15 | |[Getting Started](https://github.com/ecomfe/react-native-cn/blob/master/quick-start/GettingStarted.md)|校对中|完整|pengxing| 16 | |[Tutorial](https://github.com/ecomfe/react-native-cn/blob/master/quick-start/Tutorial.md)|校对中|完整|pengxing| 17 | |[Videos](https://github.com/ecomfe/react-native-cn/blob/master/quick-start/Videos.md)|校对中|完整|pengxing| 18 | 19 | ### GUIDES 20 | |章节|翻译状态|英文文档是否完整|负责人| 21 | |----|----|----|------| 22 | |[Style](https://github.com/ecomfe/react-native-cn/blob/master/guides/Style.md)|校对中|完整|zhoucumt| 23 | |[Gesture Responder System](https://github.com/ecomfe/react-native-cn/blob/master/guides/GestureResponderSystem.md)|校对中|完整|chendatony31| 24 | |[Native Modules (iOS)](https://github.com/ecomfe/react-native-cn/blob/master/guides/NativeModulesIOS.md)|校对中|完整|wuhy| 25 | |[Linking Libraries](https://github.com/ecomfe/react-native-cn/blob/master/guides/LinkingLibraries.md)|未开始|完整|ishenli| 26 | |[Debugging](https://github.com/ecomfe/react-native-cn/blob/master/guides/Debugging.md)|校对中|完整|zhoucumt| 27 | |[Testing](https://github.com/ecomfe/react-native-cn/blob/master/guides/Testing.md)|校对中|完整|wuhy| 28 | 29 | ### COMPONENTS 30 | |章节|翻译状态|英文文档是否完整|负责人| 31 | |----|----|----|------| 32 | |[ActivityIndicatorIOS](https://github.com/ecomfe/react-native-cn/blob/master/components/ActivityIndicatorIOS.md)|未开始|完整|未指定| 33 | |[DatePickerIOS](https://github.com/ecomfe/react-native-cn/blob/master/components/DatePickerIOS.md)|未开始|完整|未指定| 34 | |[Image](https://github.com/ecomfe/react-native-cn/blob/master/components/Image.md)|未开始|完整|未指定| 35 | |[ListView](https://github.com/ecomfe/react-native-cn/blob/master/components/ListView.md)|未开始|完整|未指定| 36 | |[MapView](https://github.com/ecomfe/react-native-cn/blob/master/components/MapView.md)|未开始|完整|未指定| 37 | |[Navigator](https://github.com/ecomfe/react-native-cn/blob/master/components/Navigator.md)|未开始|完整|未指定| 38 | |[NavigatorIOS](https://github.com/ecomfe/react-native-cn/blob/master/components/NavigatorIOS.md)|未开始|完整|未指定| 39 | |[PickerIOS](https://github.com/ecomfe/react-native-cn/blob/master/components/PickerIOS.md)|未开始|完整|未指定| 40 | |[ScrollView](https://github.com/ecomfe/react-native-cn/blob/master/components/ScrollView.md)|未开始|完整|未指定| 41 | |[SliderIOS](https://github.com/ecomfe/react-native-cn/blob/master/components/SliderIOS.md)|未开始|完整|未指定| 42 | |[SwitchIOS](https://github.com/ecomfe/react-native-cn/blob/master/components/SwitchIOS.md)|未开始|完整|未指定| 43 | |[TabBarIOS](https://github.com/ecomfe/react-native-cn/blob/master/components/TabBarIOS.md)|未开始|完整|未指定| 44 | |[Text](https://github.com/ecomfe/react-native-cn/blob/master/components/Text.md)|未开始|完整|未指定| 45 | |[TextInput](https://github.com/ecomfe/react-native-cn/blob/master/components/TextInput.md)|未开始|完整|未指定| 46 | |[TouchableHighlight](https://github.com/ecomfe/react-native-cn/blob/master/components/TouchableHighlight.md)|未开始|完整|未指定| 47 | |[TouchableOpacity](https://github.com/ecomfe/react-native-cn/blob/master/components/TouchableOpacity.md)|未开始|完整|未指定| 48 | |[TouchableWithoutFeedback](https://github.com/ecomfe/react-native-cn/blob/master/components/TouchableWithoutFeedback.md)|未开始|完整|未指定| 49 | |[View](https://github.com/ecomfe/react-native-cn/blob/master/components/View.md)|未开始|完整|未指定| 50 | |[WebView](https://github.com/ecomfe/react-native-cn/blob/master/components/WebView.md)|未开始|完整|未指定| 51 | 52 | ### APIS 53 | |章节|翻译状态|英文文档是否完整|负责人| 54 | |----|----|----|------| 55 | |[AlertIOS](https://github.com/ecomfe/react-native-cn/blob/master/apis/AlertIOS.md)|未开始|完整|未指定| 56 | |[Animation](https://github.com/ecomfe/react-native-cn/blob/master/apis/Animation.md)|未开始|完整|未指定| 57 | |[AppRegistry](https://github.com/ecomfe/react-native-cn/blob/master/apis/AppRegistry.md)|未开始|完整|未指定| 58 | |[AppStateIOS](https://github.com/ecomfe/react-native-cn/blob/master/apis/AppStateIOS.md)|未开始|完整|未指定| 59 | |[AsyncStorage](https://github.com/ecomfe/react-native-cn/blob/master/apis/AsyncStorage.md)|未开始|完整|未指定| 60 | |[CameraRoll](https://github.com/ecomfe/react-native-cn/blob/master/apis/CameraRoll.md)|未开始|完整|未指定| 61 | |[InteractionManager](https://github.com/ecomfe/react-native-cn/blob/master/apis/InteractionManager.md)|未开始|完整|未指定| 62 | |[LayoutAnimation](https://github.com/ecomfe/react-native-cn/blob/master/apis/LayoutAnimation.md)|未开始|完整|未指定| 63 | |[LinkingIOS](https://github.com/ecomfe/react-native-cn/blob/master/apis/LinkingIOS.md)|未开始|完整|未指定| 64 | |[NetInfo](https://github.com/ecomfe/react-native-cn/blob/master/apis/NetInfo.md)|未开始|完整|未指定| 65 | |[PanResponder](https://github.com/ecomfe/react-native-cn/blob/master/apis/PanResponder.md)|未开始|完整|未指定| 66 | |[PixelRatio](https://github.com/ecomfe/react-native-cn/blob/master/apis/PixelRatio.md)|未开始|完整|未指定| 67 | |[PushNotificationIOS](https://github.com/ecomfe/react-native-cn/blob/master/apis/PushNotificationIOS.md)|未开始|完整|未指定| 68 | |[StatusBarIOS](https://github.com/ecomfe/react-native-cn/blob/master/apis/StatusBarIOS.md)|未开始|完整|未指定| 69 | |[StyleSheet](https://github.com/ecomfe/react-native-cn/blob/master/apis/StyleSheet.md)|未开始|完整|未指定| 70 | |[VibrationIOS](https://github.com/ecomfe/react-native-cn/blob/master/apis/VibrationIOS.md)|未开始|完整|未指定| 71 | 72 | ### POLYFILLS 73 | |章节|翻译状态|英文文档是否完整|负责人| 74 | |----|----|----|------| 75 | |[Flexbox](https://github.com/ecomfe/react-native-cn/blob/master/polyfills/Flexbox.md)|未开始|完整|未指定| 76 | |[Geolocation](https://github.com/ecomfe/react-native-cn/blob/master/polyfills/Geolocation.md)|未开始|完整|未指定| 77 | |[Network](https://github.com/ecomfe/react-native-cn/blob/master/polyfills/Network.md)|未开始|完整|未指定| 78 | |[Timers](https://github.com/ecomfe/react-native-cn/blob/master/polyfills/Timers.md)|校对中|完整|franckchen| 79 | 80 | * 状态包括:未开始|完整、进行中、校对中、完成 81 | -------------------------------------------------------------------------------- /apis/PushNotificationIOS.md: -------------------------------------------------------------------------------- 1 | Handle push notifications for your app, including permission handling and icon badge number. 2 | 3 | To get up and running, [configure your notifications with Apple](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/ConfiguringPushNotifications/ConfiguringPushNotifications.html) and your server-side system. To get an idea, [this is the Parse guide](https://parse.com/tutorials/ios-push-notifications). 4 | 5 | ## Methods 6 | 7 | static **setApplicationIconBadgeNumber**(number: number) 8 | 9 | Sets the badge number for the app icon on the home screen 10 | 11 | static **getApplicationIconBadgeNumber**(callback: Function) 12 | 13 | Gets the current badge number for the app icon on the home screen 14 | 15 | static **addEventListener**(type: string, handler: Function) 16 | 17 | Attaches a listener to remote notifications while the app is running in the foreground or the background. 18 | 19 | The handler will get be invoked with an instance of `PushNotificationIOS` 20 | 21 | static **requestPermissions**() 22 | 23 | Requests all notification permissions from iOS, prompting the user's dialog box. 24 | 25 | static **checkPermissions**(callback: Function) 26 | 27 | See what push permissions are currently enabled. callback will be invoked with a `permissions` object: 28 | 29 | * `alert` :boolean 30 | * `badge` :boolean 31 | * `sound` :boolean 32 | 33 | static **removeEventListener**(type: string, handler: Function) 34 | 35 | Removes the event listener. Do this in componentWillUnmount to prevent memory leaks 36 | 37 | static **popInitialNotification**() 38 | 39 | An initial notification will be available if the app was cold-launched from a notification. 40 | 41 | The first caller of `popInitialNotification` will get the initial notification object, or null. Subsequent invocations will return null. 42 | 43 | **constructor**(nativeNotif) 44 | 45 | You will never need to instansiate `PushNotificationIOS` yourself. Listening to the `notification` event and invoking `popInitialNotification` is sufficient 46 | 47 | **getMessage**() 48 | 49 | An alias for `getAlert` to get the notification's main message string 50 | 51 | **getSound**() 52 | 53 | Gets the sound string from the `aps` object 54 | 55 | **getAlert**() 56 | 57 | Gets the notification's main message from the `aps` object 58 | 59 | **getBadgeCount**() 60 | 61 | Gets the badge count number from the `aps` object 62 | 63 | **getData**() 64 | 65 | Gets the data object on the notif 66 | 67 | ## Examples 68 | 69 | ```javascript 70 | 'use strict'; 71 | 72 | var React = require('react-native'); 73 | var { 74 | AlertIOS, 75 | PushNotificationIOS, 76 | StyleSheet, 77 | Text, 78 | TouchableHighlight, 79 | View, 80 | } = React; 81 | 82 | var Button = React.createClass({ 83 | render: function() { 84 | return ( 85 | 89 | 90 | {this.props.label} 91 | 92 | 93 | ); 94 | } 95 | }); 96 | 97 | class NotificationExample extends React.Component { 98 | componentWillMount() { 99 | PushNotificationIOS.addEventListener('notification', this._onNotification); 100 | } 101 | 102 | componentWillUnmount() { 103 | PushNotificationIOS.removeEventListener('notification', this._onNotification); 104 | } 105 | 106 | render() { 107 | return ( 108 | 109 |