mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
268 lines
56 KiB
HTML
268 lines
56 KiB
HTML
<!DOCTYPE html><html><head><title>Native UI Components</title><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width"><meta property="fb:app_id" content="1677033832619985"><meta property="fb:admins" content="121800083"><meta property="og:site_name" content="React Native"><meta property="og:title" content="Native UI Components"><meta property="og:url" content="https://facebook.github.io/react-native/index.html"><meta property="og:image" content="http://facebook.github.io/react-native/img/opengraph.png"><meta property="og:description" content="A framework for building native apps using React"><meta name="twitter:site" content="@reactnative"><meta name="twitter:card" content="summary"><meta property="og:type" content="website"><base href="/react-native/"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"><link rel="shortcut icon" href="img/favicon.png?2"><link rel="stylesheet" href="css/react-native.css"><script type="text/javascript" src="//use.typekit.net/vqa1hcx.js"></script><script type="text/javascript">try{Typekit.load();}catch(e){}</script></head><body><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, "script", "twitter-wjs"));</script><div class="container"><div class="nav-main"><div class="wrap"><a class="nav-home" href=""><img src="img/header_logo.png">React Native</a><a class="nav-version" href="/react-native/versions.html">0.34</a><div class="nav-site-wrapper"><ul class="nav-site nav-site-internal"><li><a href="docs/getting-started.html" class="active" data-target=".nav-docs">Docs</a></li><li><a href="support.html" class="">Support</a></li><li><a href="showcase.html" class="">Showcase</a></li><li><a href="/react-native/blog/" class="">Blog</a></li></ul><div class="algolia-search-wrapper"><input id="algolia-doc-search" tabindex="0" type="text" placeholder="Search docs..."></div><ul class="nav-site nav-site-external"><li><a href="https://github.com/facebook/react-native" class="">GitHub</a></li><li><a href="http://facebook.github.io/react" class="">React</a></li></ul></div></div></div><section class="content wrap documentationContent"><div class="nav-docs"><div class="nav-docs-viewport"><div class="nav-docs-section"><h3>The Basics</h3><ul><li><a style="margin-left:0;" class="" href="docs/getting-started.html">Getting Started</a></li><li><a style="margin-left:0;" class="" href="docs/tutorial.html">Tutorial</a></li><li><a style="margin-left:0;" class="" href="docs/props.html">Props</a></li><li><a style="margin-left:0;" class="" href="docs/state.html">State</a></li><li><a style="margin-left:0;" class="" href="docs/style.html">Style</a></li><li><a style="margin-left:0;" class="" href="docs/height-and-width.html">Height and Width</a></li><li><a style="margin-left:0;" class="" href="docs/flexbox.html">Layout with Flexbox</a></li><li><a style="margin-left:0;" class="" href="docs/handling-text-input.html">Handling Text Input</a></li><li><a style="margin-left:0;" class="" href="docs/using-a-scrollview.html">Using a ScrollView</a></li><li><a style="margin-left:0;" class="" href="docs/using-a-listview.html">Using a ListView</a></li><li><a style="margin-left:0;" class="" href="docs/network.html">Networking</a></li><li><a style="margin-left:0;" class="" href="docs/using-navigators.html">Using Navigators</a></li><li><a style="margin-left:0;" class="" href="docs/more-resources.html">More Resources</a></li></ul></div><div class="nav-docs-section"><h3>Guides</h3><ul><li><a style="margin-left:0;" class="" href="docs/integration-with-existing-apps.html">Integration With Existing Apps</a></li><li><a style="margin-left:0;" class="" href="docs/colors.html">Colors</a></li><li><a style="margin-left:0;" class="" href="docs/images.html">Images</a></li><li><a style="margin-left:0;" class="" href="docs/handling-touches.html">Handling Touches</a></li><li><a style="margin-left:0;" class="" href="docs/animations.html">Animations</a></li><li><a style="margin-left:0;" class="" href="docs/accessibility.html">Accessibility</a></li><li><a style="margin-left:0;" class="" href="docs/timers.html">Timers</a></li><li><a style="margin-left:0;" class="" href="docs/direct-manipulation.html">Direct Manipulation</a></li><li><a style="margin-left:0;" class="" href="docs/debugging.html">Debugging</a></li><li><a style="margin-left:0;" class="" href="docs/testing.html">Testing</a></li><li><a style="margin-left:0;" class="" href="docs/javascript-environment.html">JavaScript Environment</a></li><li><a style="margin-left:0;" class="" href="docs/navigation.html">Navigation</a></li><li><a style="margin-left:0;" class="" href="docs/performance.html">Performance</a></li><li><a style="margin-left:0;" class="" href="docs/upgrading.html">Upgrading</a></li><li><a style="margin-left:0;" class="" href="docs/platform-specific-code.html">Platform Specific Code</a></li><li><a style="margin-left:0;" class="" href="docs/gesture-responder-system.html">Gesture Responder System</a></li></ul></div><div class="nav-docs-section"><h3>Guides (iOS)</h3><ul><li><a style="margin-left:0;" class="" href="docs/native-modules-ios.html">Native Modules</a></li><li><a style="margin-left:0;" class="active" href="docs/native-components-ios.html">Native UI Components</a></li><li><a style="margin-left:0;" class="" href="docs/linking-libraries-ios.html">Linking Libraries</a></li><li><a style="margin-left:0;" class="" href="docs/running-on-device-ios.html">Running On Device</a></li><li><a style="margin-left:0;" class="" href="docs/running-on-simulator-ios.html">Running On Simulator</a></li><li><a style="margin-left:0;" class="" href="docs/communication-ios.html">Communication between native and React Native</a></li></ul></div><div class="nav-docs-section"><h3>Guides (Android)</h3><ul><li><a style="margin-left:0;" class="" href="docs/native-modules-android.html">Native Modules</a></li><li><a style="margin-left:0;" class="" href="docs/native-components-android.html">Native UI Components</a></li><li><a style="margin-left:0;" class="" href="docs/running-on-device-android.html">Running On Device</a></li><li><a style="margin-left:0;" class="" href="docs/signed-apk-android.html">Generating Signed APK</a></li><li><a style="margin-left:0;" class="" href="docs/android-ui-performance.html">Profiling Android UI Performance</a></li><li><a style="margin-left:0;" class="" href="docs/android-building-from-source.html">Building React Native from source</a></li></ul></div><div class="nav-docs-section"><h3>components</h3><ul><li><a style="margin-left:0;" class="" href="docs/activityindicator.html">ActivityIndicator</a></li><li><a style="margin-left:0;" class="" href="docs/activityindicatorios.html">ActivityIndicatorIOS</a></li><li><a style="margin-left:0;" class="" href="docs/datepickerios.html">DatePickerIOS</a></li><li><a style="margin-left:0;" class="" href="docs/drawerlayoutandroid.html">DrawerLayoutAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/image.html">Image</a></li><li><a style="margin-left:0;" class="" href="docs/keyboardavoidingview.html">KeyboardAvoidingView</a></li><li><a style="margin-left:0;" class="" href="docs/listview.html">ListView</a></li><li><a style="margin-left:0;" class="" href="docs/mapview.html">MapView</a></li><li><a style="margin-left:0;" class="" href="docs/modal.html">Modal</a></li><li><a style="margin-left:0;" class="" href="docs/navigator.html">Navigator</a></li><li><a style="margin-left:0;" class="" href="docs/navigatorios.html">NavigatorIOS</a></li><li><a style="margin-left:0;" class="" href="docs/picker.html">Picker</a></li><li><a style="margin-left:0;" class="" href="docs/pickerios.html">PickerIOS</a></li><li><a style="margin-left:0;" class="" href="docs/progressbarandroid.html">ProgressBarAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/progressviewios.html">ProgressViewIOS</a></li><li><a style="margin-left:0;" class="" href="docs/refreshcontrol.html">RefreshControl</a></li><li><a style="margin-left:0;" class="" href="docs/scrollview.html">ScrollView</a></li><li><a style="margin-left:0;" class="" href="docs/segmentedcontrolios.html">SegmentedControlIOS</a></li><li><a style="margin-left:0;" class="" href="docs/slider.html">Slider</a></li><li><a style="margin-left:0;" class="" href="docs/sliderios.html">SliderIOS</a></li><li><a style="margin-left:0;" class="" href="docs/statusbar.html">StatusBar</a></li><li><a style="margin-left:0;" class="" href="docs/snapshotviewios.html">SnapshotViewIOS</a></li><li><a style="margin-left:0;" class="" href="docs/switch.html">Switch</a></li><li><a style="margin-left:0;" class="" href="docs/switchandroid.html">SwitchAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/switchios.html">SwitchIOS</a></li><li><a style="margin-left:0;" class="" href="docs/tabbarios.html">TabBarIOS</a></li><li><a style="margin-left:0;" class="" href="docs/tabbarios-item.html">TabBarIOS.Item</a></li><li><a style="margin-left:0;" class="" href="docs/text.html">Text</a></li><li><a style="margin-left:0;" class="" href="docs/textinput.html">TextInput</a></li><li><a style="margin-left:0;" class="" href="docs/toolbarandroid.html">ToolbarAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/touchablehighlight.html">TouchableHighlight</a></li><li><a style="margin-left:0;" class="" href="docs/touchablenativefeedback.html">TouchableNativeFeedback</a></li><li><a style="margin-left:0;" class="" href="docs/touchableopacity.html">TouchableOpacity</a></li><li><a style="margin-left:0;" class="" href="docs/touchablewithoutfeedback.html">TouchableWithoutFeedback</a></li><li><a style="margin-left:0;" class="" href="docs/view.html">View</a></li><li><a style="margin-left:0;" class="" href="docs/viewpagerandroid.html">ViewPagerAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/webview.html">WebView</a></li></ul></div><div class="nav-docs-section"><h3>apis</h3><ul><li><a style="margin-left:0;" class="" href="docs/actionsheetios.html">ActionSheetIOS</a></li><li><a style="margin-left:0;" class="" href="docs/adsupportios.html">AdSupportIOS</a></li><li><a style="margin-left:0;" class="" href="docs/alert.html">Alert</a></li><li><a style="margin-left:0;" class="" href="docs/alertios.html">AlertIOS</a></li><li><a style="margin-left:0;" class="" href="docs/animated.html">Animated</a></li><li><a style="margin-left:0;" class="" href="docs/appregistry.html">AppRegistry</a></li><li><a style="margin-left:0;" class="" href="docs/appstate.html">AppState</a></li><li><a style="margin-left:0;" class="" href="docs/asyncstorage.html">AsyncStorage</a></li><li><a style="margin-left:0;" class="" href="docs/backandroid.html">BackAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/cameraroll.html">CameraRoll</a></li><li><a style="margin-left:0;" class="" href="docs/clipboard.html">Clipboard</a></li><li><a style="margin-left:0;" class="" href="docs/datepickerandroid.html">DatePickerAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/dimensions.html">Dimensions</a></li><li><a style="margin-left:0;" class="" href="docs/easing.html">Easing</a></li><li><a style="margin-left:0;" class="" href="docs/geolocation.html">Geolocation</a></li><li><a style="margin-left:0;" class="" href="docs/imageeditor.html">ImageEditor</a></li><li><a style="margin-left:0;" class="" href="docs/imagepickerios.html">ImagePickerIOS</a></li><li><a style="margin-left:0;" class="" href="docs/imagestore.html">ImageStore</a></li><li><a style="margin-left:0;" class="" href="docs/intentandroid.html">IntentAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/interactionmanager.html">InteractionManager</a></li><li><a style="margin-left:0;" class="" href="docs/layoutanimation.html">LayoutAnimation</a></li><li><a style="margin-left:0;" class="" href="docs/linking.html">Linking</a></li><li><a style="margin-left:0;" class="" href="docs/nativemethodsmixin.html">NativeMethodsMixin</a></li><li><a style="margin-left:0;" class="" href="docs/nativemodules.html">NativeModules</a></li><li><a style="margin-left:0;" class="" href="docs/netinfo.html">NetInfo</a></li><li><a style="margin-left:0;" class="" href="docs/panresponder.html">PanResponder</a></li><li><a style="margin-left:0;" class="" href="docs/permissionsandroid.html">PermissionsAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/pixelratio.html">PixelRatio</a></li><li><a style="margin-left:0;" class="" href="docs/pushnotificationios.html">PushNotificationIOS</a></li><li><a style="margin-left:0;" class="" href="docs/settings.html">Settings</a></li><li><a style="margin-left:0;" class="" href="docs/statusbarios.html">StatusBarIOS</a></li><li><a style="margin-left:0;" class="" href="docs/stylesheet.html">StyleSheet</a></li><li><a style="margin-left:0;" class="" href="docs/systrace.html">Systrace</a></li><li><a style="margin-left:0;" class="" href="docs/timepickerandroid.html">TimePickerAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/toastandroid.html">ToastAndroid</a></li><li><a style="margin-left:0;" class="" href="docs/vibration.html">Vibration</a></li><li><a style="margin-left:0;" class="" href="docs/vibrationios.html">VibrationIOS</a></li><li><a style="margin-left:0;" class="" href="docs/layout-props.html">Layout Props</a></li><li><a style="margin-left:0;" class="" href="docs/shadow-props.html">Shadow Props</a></li></ul></div></div></div><div class="inner-content"><a id="content"></a><h1><a class="anchor" name="native-ui-components"></a>Native UI Components <a class="hash-link" href="docs/native-components-ios.html#native-ui-components">#</a></h1><div><p>There are tons of native UI widgets out there ready to be used in the latest apps - some of them are part of the platform, others are available as third-party libraries, and still more might be in use in your very own portfolio. React Native has several of the most critical platform components already wrapped, like <code>ScrollView</code> and <code>TextInput</code>, but not all of them, and certainly not ones you might have written yourself for a previous app. Fortunately, it's quite easy to wrap up these existing components for seamless integration with your React Native application.</p><p>Like the native module guide, this too is a more advanced guide that assumes you are somewhat familiar with iOS programming. This guide will show you how to build a native UI component, walking you through the implementation of a subset of the existing <code>MapView</code> component available in the core React Native library.</p><h2><a class="anchor" name="ios-mapview-example"></a>iOS MapView example <a class="hash-link" href="docs/native-components-ios.html#ios-mapview-example">#</a></h2><p>Let's say we want to add an interactive Map to our app - might as well use <a href="https://developer.apple.com/library/prerelease/mac/documentation/MapKit/Reference/MKMapView_Class/index.html" target="_blank"><code>MKMapView</code></a>, we just need to make it usable from JavaScript.</p><p>Native views are created and manipulated by subclasses of <code>RCTViewManager</code>. These subclasses are similar in function to view controllers, but are essentially singletons - only one instance of each is created by the bridge. They vend native views to the <code>RCTUIManager</code>, which delegates back to them to set and update the properties of the views as necessary. The <code>RCTViewManager</code>s are also typically the delegates for the views, sending events back to JavaScript via the bridge.</p><p>Vending a view is simple:</p><ul><li>Create the basic subclass.</li><li>Add the <code>RCT_EXPORT_MODULE()</code> marker macro.</li><li>Implement the <code>-(UIView *)view</code> method.</li></ul><div class="prism language-javascript"><span class="token comment" spellcheck="true">// RCTMapManager.m
|
||
</span>#import <MapKit<span class="token operator">/</span>MapKit<span class="token punctuation">.</span>h<span class="token operator">></span>
|
||
|
||
#import <span class="token string">"RCTViewManager.h"</span>
|
||
|
||
@interface <span class="token class-name">RCTMapManager</span> <span class="token punctuation">:</span> RCTViewManager
|
||
@end
|
||
|
||
@implementation RCTMapManager
|
||
|
||
<span class="token function">RCT_EXPORT_MODULE<span class="token punctuation">(</span></span><span class="token punctuation">)</span>
|
||
|
||
<span class="token operator">-</span> <span class="token punctuation">(</span>UIView <span class="token operator">*</span><span class="token punctuation">)</span>view
|
||
<span class="token punctuation">{</span>
|
||
<span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token punctuation">[</span>MKMapView alloc<span class="token punctuation">]</span> init<span class="token punctuation">]</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
|
||
@end</div><p><strong>Note:</strong> Do not attempt to set the <code>frame</code> or <code>backgroundColor</code> properties on the <code>UIView</code> instance that you vend through the <code>-view</code> method. React Native will overwrite the values set by your custom class in order to match your JavaScript component's layout props. If you need this granularity of control it might be better to wrap the <code>UIView</code> instance you want to style in another <code>UIView</code> and return the wrapper <code>UIView</code> instead. See <a href="https://github.com/facebook/react-native/issues/2948" target="_blank">Issue 2948</a> for more context.</p><p>Then you just need a little bit of JavaScript to make this a usable React component:</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// MapView.js
|
||
</span>
|
||
import <span class="token punctuation">{</span> requireNativeComponent <span class="token punctuation">}</span> from <span class="token string">'react-native'</span><span class="token punctuation">;</span>
|
||
<span class="token comment" spellcheck="true">
|
||
// requireNativeComponent automatically resolves this to "RCTMapManager"
|
||
</span>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token function">requireNativeComponent<span class="token punctuation">(</span></span><span class="token string">'RCTMap'</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span></div><p>This is now a fully-functioning native map view component in JavaScript, complete with pinch-zoom and other native gesture support. We can't really control it from JavaScript yet, though :(</p><h2><a class="anchor" name="properties"></a>Properties <a class="hash-link" href="docs/native-components-ios.html#properties">#</a></h2><p>The first thing we can do to make this component more usable is to bridge over some native properties. Let's say we want to be able to disable pitch control and specify the visible region. Disabling pitch is a simple boolean, so we add this one line:</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// RCTMapManager.m
|
||
</span><span class="token function">RCT_EXPORT_VIEW_PROPERTY<span class="token punctuation">(</span></span>pitchEnabled<span class="token punctuation">,</span> BOOL<span class="token punctuation">)</span></div><p>Note that we explicitly specify the type as <code>BOOL</code> - React Native uses <code>RCTConvert</code> under the hood to convert all sorts of different data types when talking over the bridge, and bad values will show convenient "RedBox" errors to let you know there is an issue ASAP. When things are straightforward like this, the whole implementation is taken care of for you by this macro.</p><p>Now to actually disable pitch, we set the property in JS:</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// MyApp.js
|
||
</span><MapView pitchEnabled<span class="token operator">=</span><span class="token punctuation">{</span><span class="token boolean">false</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span></div><p>This isn't very well documented though - in order to know what properties are available and what values they accept, the client of your new component needs to dig through the Objective-C code. To make this better, let's make a wrapper component and document the interface with React <code>PropTypes</code>:</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// MapView.js
|
||
</span>import React from <span class="token string">'react'</span><span class="token punctuation">;</span>
|
||
import <span class="token punctuation">{</span> requireNativeComponent <span class="token punctuation">}</span> from <span class="token string">'react-native'</span><span class="token punctuation">;</span>
|
||
|
||
class <span class="token class-name">MapView</span> extends <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
|
||
<span class="token function">render<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||
<span class="token keyword">return</span> <RCTMap <span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span>
|
||
|
||
MapView<span class="token punctuation">.</span>propTypes <span class="token operator">=</span> <span class="token punctuation">{</span>
|
||
<span class="token comment" spellcheck="true">/**
|
||
* 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.
|
||
*/</span>
|
||
pitchEnabled<span class="token punctuation">:</span> React<span class="token punctuation">.</span>PropTypes<span class="token punctuation">.</span>bool<span class="token punctuation">,</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||
|
||
<span class="token keyword">var</span> RCTMap <span class="token operator">=</span> <span class="token function">requireNativeComponent<span class="token punctuation">(</span></span><span class="token string">'RCTMap'</span><span class="token punctuation">,</span> MapView<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||
|
||
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> MapView<span class="token punctuation">;</span></div><p>Now we have a nicely documented wrapper component that is easy to work with. Note that we changed the second argument to <code>requireNativeComponent</code> from <code>null</code> to the new <code>MapView</code> wrapper component. This allows the infrastructure to verify that the propTypes match the native props to reduce the chances of mismatches between the ObjC and JS code.</p><p>Next, let's add the more complex <code>region</code> prop. We start by adding the native code:</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// RCTMapManager.m
|
||
</span><span class="token function">RCT_CUSTOM_VIEW_PROPERTY<span class="token punctuation">(</span></span>region<span class="token punctuation">,</span> MKCoordinateRegion<span class="token punctuation">,</span> RCTMap<span class="token punctuation">)</span>
|
||
<span class="token punctuation">{</span>
|
||
<span class="token punctuation">[</span>view setRegion<span class="token punctuation">:</span>json <span class="token operator">?</span> <span class="token punctuation">[</span>RCTConvert MKCoordinateRegion<span class="token punctuation">:</span>json<span class="token punctuation">]</span> <span class="token punctuation">:</span> defaultView<span class="token punctuation">.</span>region animated<span class="token punctuation">:</span>YES<span class="token punctuation">]</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span></div><p>Ok, this is more complicated than the simple <code>BOOL</code> case we had before. Now we have a <code>MKCoordinateRegion</code> type that needs a conversion function, and we have custom code so that the view will animate when we set the region from JS. Within the function body that we provide, <code>json</code> refers to the raw value that has been passed from JS. There is also a <code>view</code> variable which gives us access to the manager's view instance, and a <code>defaultView</code> that we use to reset the property back to the default value if JS sends us a null sentinel.</p><p>You could write any conversion function you want for your view - here is the implementation for <code>MKCoordinateRegion</code> via two categories on <code>RCTConvert</code>:</p><div class="prism language-javascript">@implementation <span class="token function">RCTConvert<span class="token punctuation">(</span></span>CoreLocation<span class="token punctuation">)</span>
|
||
|
||
<span class="token function">RCT_CONVERTER<span class="token punctuation">(</span></span>CLLocationDegrees<span class="token punctuation">,</span> CLLocationDegrees<span class="token punctuation">,</span> doubleValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||
<span class="token function">RCT_CONVERTER<span class="token punctuation">(</span></span>CLLocationDistance<span class="token punctuation">,</span> CLLocationDistance<span class="token punctuation">,</span> doubleValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||
|
||
<span class="token operator">+</span> <span class="token punctuation">(</span>CLLocationCoordinate2D<span class="token punctuation">)</span>CLLocationCoordinate2D<span class="token punctuation">:</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span>json
|
||
<span class="token punctuation">{</span>
|
||
json <span class="token operator">=</span> <span class="token punctuation">[</span>self NSDictionary<span class="token punctuation">:</span>json<span class="token punctuation">]</span><span class="token punctuation">;</span>
|
||
<span class="token keyword">return</span> <span class="token punctuation">(</span>CLLocationCoordinate2D<span class="token punctuation">)</span><span class="token punctuation">{</span>
|
||
<span class="token punctuation">[</span>self CLLocationDegrees<span class="token punctuation">:</span>json<span class="token punctuation">[</span>@<span class="token string">"latitude"</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">[</span>self CLLocationDegrees<span class="token punctuation">:</span>json<span class="token punctuation">[</span>@<span class="token string">"longitude"</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
|
||
@end
|
||
|
||
@implementation <span class="token function">RCTConvert<span class="token punctuation">(</span></span>MapKit<span class="token punctuation">)</span>
|
||
|
||
<span class="token operator">+</span> <span class="token punctuation">(</span>MKCoordinateSpan<span class="token punctuation">)</span>MKCoordinateSpan<span class="token punctuation">:</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span>json
|
||
<span class="token punctuation">{</span>
|
||
json <span class="token operator">=</span> <span class="token punctuation">[</span>self NSDictionary<span class="token punctuation">:</span>json<span class="token punctuation">]</span><span class="token punctuation">;</span>
|
||
<span class="token keyword">return</span> <span class="token punctuation">(</span>MKCoordinateSpan<span class="token punctuation">)</span><span class="token punctuation">{</span>
|
||
<span class="token punctuation">[</span>self CLLocationDegrees<span class="token punctuation">:</span>json<span class="token punctuation">[</span>@<span class="token string">"latitudeDelta"</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">[</span>self CLLocationDegrees<span class="token punctuation">:</span>json<span class="token punctuation">[</span>@<span class="token string">"longitudeDelta"</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
|
||
<span class="token operator">+</span> <span class="token punctuation">(</span>MKCoordinateRegion<span class="token punctuation">)</span>MKCoordinateRegion<span class="token punctuation">:</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span>json
|
||
<span class="token punctuation">{</span>
|
||
<span class="token keyword">return</span> <span class="token punctuation">(</span>MKCoordinateRegion<span class="token punctuation">)</span><span class="token punctuation">{</span>
|
||
<span class="token punctuation">[</span>self CLLocationCoordinate2D<span class="token punctuation">:</span>json<span class="token punctuation">]</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">[</span>self MKCoordinateSpan<span class="token punctuation">:</span>json<span class="token punctuation">]</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span></div><p>These conversion functions are designed to safely process any JSON that the JS might throw at them by displaying "RedBox" errors and returning standard initialization values when missing keys or other developer errors are encountered.</p><p>To finish up support for the <code>region</code> prop, we need to document it in <code>propTypes</code> (or we'll get an error that the native prop is undocumented), then we can set it just like any other prop:</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// MapView.js
|
||
</span>
|
||
MapView<span class="token punctuation">.</span>propTypes <span class="token operator">=</span> <span class="token punctuation">{</span>
|
||
<span class="token comment" spellcheck="true">/**
|
||
* 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.
|
||
*/</span>
|
||
pitchEnabled<span class="token punctuation">:</span> React<span class="token punctuation">.</span>PropTypes<span class="token punctuation">.</span>bool<span class="token punctuation">,</span>
|
||
|
||
<span class="token comment" spellcheck="true">/**
|
||
* The region to be displayed by the map.
|
||
*
|
||
* The region is defined by the center coordinates and the span of
|
||
* coordinates to display.
|
||
*/</span>
|
||
region<span class="token punctuation">:</span> React<span class="token punctuation">.</span>PropTypes<span class="token punctuation">.</span><span class="token function">shape<span class="token punctuation">(</span></span><span class="token punctuation">{</span>
|
||
<span class="token comment" spellcheck="true">/**
|
||
* Coordinates for the center of the map.
|
||
*/</span>
|
||
latitude<span class="token punctuation">:</span> React<span class="token punctuation">.</span>PropTypes<span class="token punctuation">.</span>number<span class="token punctuation">.</span>isRequired<span class="token punctuation">,</span>
|
||
longitude<span class="token punctuation">:</span> React<span class="token punctuation">.</span>PropTypes<span class="token punctuation">.</span>number<span class="token punctuation">.</span>isRequired<span class="token punctuation">,</span>
|
||
|
||
<span class="token comment" spellcheck="true">/**
|
||
* Distance between the minimum and the maximum latitude/longitude
|
||
* to be displayed.
|
||
*/</span>
|
||
latitudeDelta<span class="token punctuation">:</span> React<span class="token punctuation">.</span>PropTypes<span class="token punctuation">.</span>number<span class="token punctuation">.</span>isRequired<span class="token punctuation">,</span>
|
||
longitudeDelta<span class="token punctuation">:</span> React<span class="token punctuation">.</span>PropTypes<span class="token punctuation">.</span>number<span class="token punctuation">.</span>isRequired<span class="token punctuation">,</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||
<span class="token comment" spellcheck="true">
|
||
// MyApp.js
|
||
</span>
|
||
<span class="token function">render<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||
<span class="token keyword">var</span> region <span class="token operator">=</span> <span class="token punctuation">{</span>
|
||
latitude<span class="token punctuation">:</span> <span class="token number">37.48</span><span class="token punctuation">,</span>
|
||
longitude<span class="token punctuation">:</span> <span class="token operator">-</span><span class="token number">122.16</span><span class="token punctuation">,</span>
|
||
latitudeDelta<span class="token punctuation">:</span> <span class="token number">0.1</span><span class="token punctuation">,</span>
|
||
longitudeDelta<span class="token punctuation">:</span> <span class="token number">0.1</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||
<span class="token keyword">return</span> <MapView region<span class="token operator">=</span><span class="token punctuation">{</span>region<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span></div><p>Here you can see that the shape of the region is explicit in the JS documentation - ideally we could codegen some of this stuff, but that's not happening yet.</p><p>Sometimes you'll have some special properties that you need to expose for the native component, but don't actually want them as part of the API for the associated React component. For example, <code>Switch</code> has a custom <code>onChange</code> handler for the raw native event, and exposes an <code>onValueChange</code> handler property that is invoked with just the boolean value rather than the raw event. Since you don't want these native only properties to be part of the API, you don't want to put them in <code>propTypes</code>, but if you don't you'll get an error. The solution is simply to call them out via the <code>nativeOnly</code> option, e.g.</p><div class="prism language-javascript"><span class="token keyword">var</span> RCTSwitch <span class="token operator">=</span> <span class="token function">requireNativeComponent<span class="token punctuation">(</span></span><span class="token string">'RCTSwitch'</span><span class="token punctuation">,</span> Switch<span class="token punctuation">,</span> <span class="token punctuation">{</span>
|
||
nativeOnly<span class="token punctuation">:</span> <span class="token punctuation">{</span> onChange<span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></div><h2><a class="anchor" name="events"></a>Events <a class="hash-link" href="docs/native-components-ios.html#events">#</a></h2><p>So now we have a native map component that we can control easily from JS, but how do we deal with events from the user, like pinch-zooms or panning to change the visible region? The key is to declare an event handler property on <code>RCTMapManager</code>, make it a delegate for all the views it vends, and forward events to JS by calling the event handler block from the native view. This looks like so (simplified from the full implementation):</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// RCTMap.h
|
||
</span>
|
||
#import <MapKit<span class="token operator">/</span>MapKit<span class="token punctuation">.</span>h<span class="token operator">></span>
|
||
|
||
#import <span class="token string">"RCTComponent.h"</span>
|
||
|
||
@interface <span class="token class-name">RCTMap</span><span class="token punctuation">:</span> MKMapView
|
||
|
||
@property <span class="token punctuation">(</span>nonatomic<span class="token punctuation">,</span> copy<span class="token punctuation">)</span> RCTBubblingEventBlock onChange<span class="token punctuation">;</span>
|
||
|
||
@end</div><div class="prism language-javascript"><span class="token comment" spellcheck="true">// RCTMap.m
|
||
</span>
|
||
#import <span class="token string">"RCTMap.h"</span>
|
||
|
||
@implementation RCTMap
|
||
|
||
@end</div><div class="prism language-javascript"><span class="token comment" spellcheck="true">// RCTMapManager.m
|
||
</span>
|
||
#import <span class="token string">"RCTMapManager.h"</span>
|
||
|
||
#import <MapKit<span class="token operator">/</span>MapKit<span class="token punctuation">.</span>h<span class="token operator">></span>
|
||
|
||
#import <span class="token string">"RCTMap.h"</span>
|
||
#import <span class="token string">"UIView+React.h"</span>
|
||
|
||
@interface <span class="token class-name">RCTMapManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <MKMapViewDelegate<span class="token operator">></span>
|
||
@end
|
||
|
||
@implementation RCTMapManager
|
||
|
||
<span class="token function">RCT_EXPORT_MODULE<span class="token punctuation">(</span></span><span class="token punctuation">)</span>
|
||
|
||
<span class="token function">RCT_EXPORT_VIEW_PROPERTY<span class="token punctuation">(</span></span>onChange<span class="token punctuation">,</span> RCTBubblingEventBlock<span class="token punctuation">)</span>
|
||
|
||
<span class="token operator">-</span> <span class="token punctuation">(</span>UIView <span class="token operator">*</span><span class="token punctuation">)</span>view
|
||
<span class="token punctuation">{</span>
|
||
RCTMap <span class="token operator">*</span>map <span class="token operator">=</span> <span class="token punctuation">[</span>RCTMap <span class="token keyword">new</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
|
||
map<span class="token punctuation">.</span>delegate <span class="token operator">=</span> self<span class="token punctuation">;</span>
|
||
<span class="token keyword">return</span> map<span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
|
||
#pragma mark MKMapViewDelegate
|
||
|
||
<span class="token operator">-</span> <span class="token punctuation">(</span>void<span class="token punctuation">)</span>mapView<span class="token punctuation">:</span><span class="token punctuation">(</span>RCTMap <span class="token operator">*</span><span class="token punctuation">)</span>mapView regionDidChangeAnimated<span class="token punctuation">:</span><span class="token punctuation">(</span>BOOL<span class="token punctuation">)</span>animated
|
||
<span class="token punctuation">{</span>
|
||
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>mapView<span class="token punctuation">.</span>onChange<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||
<span class="token keyword">return</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
|
||
MKCoordinateRegion region <span class="token operator">=</span> mapView<span class="token punctuation">.</span>region<span class="token punctuation">;</span>
|
||
mapView<span class="token punctuation">.</span><span class="token function">onChange<span class="token punctuation">(</span></span>@<span class="token punctuation">{</span>
|
||
@<span class="token string">"region"</span><span class="token punctuation">:</span> @<span class="token punctuation">{</span>
|
||
@<span class="token string">"latitude"</span><span class="token punctuation">:</span> @<span class="token punctuation">(</span>region<span class="token punctuation">.</span>center<span class="token punctuation">.</span>latitude<span class="token punctuation">)</span><span class="token punctuation">,</span>
|
||
@<span class="token string">"longitude"</span><span class="token punctuation">:</span> @<span class="token punctuation">(</span>region<span class="token punctuation">.</span>center<span class="token punctuation">.</span>longitude<span class="token punctuation">)</span><span class="token punctuation">,</span>
|
||
@<span class="token string">"latitudeDelta"</span><span class="token punctuation">:</span> @<span class="token punctuation">(</span>region<span class="token punctuation">.</span>span<span class="token punctuation">.</span>latitudeDelta<span class="token punctuation">)</span><span class="token punctuation">,</span>
|
||
@<span class="token string">"longitudeDelta"</span><span class="token punctuation">:</span> @<span class="token punctuation">(</span>region<span class="token punctuation">.</span>span<span class="token punctuation">.</span>longitudeDelta<span class="token punctuation">)</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span></div><p>You can see we're adding an event handler property to the view by subclassing <code>MKMapView</code>. Then we're exposing the <code>onChange</code> event handler property and setting the manager as the delegate for every view that it vends. Finally, in the delegate method <code>-mapView:regionDidChangeAnimated:</code> the event handler block is called on the corresponding view with the region data. Calling the <code>onChange</code> event handler block results in calling the same callback prop in JavaScript. This callback is invoked with the raw event, which we typically process in the wrapper component to make a simpler API:</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// MapView.js
|
||
</span>
|
||
class <span class="token class-name">MapView</span> extends <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
|
||
<span class="token function">constructor<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||
<span class="token keyword">this</span><span class="token punctuation">.</span>_onChange <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_onChange<span class="token punctuation">.</span><span class="token function">bind<span class="token punctuation">(</span></span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token function">_onChange<span class="token punctuation">(</span></span>event<span class="token punctuation">:</span> Event<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>onRegionChange<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||
<span class="token keyword">return</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span><span class="token function">onRegionChange<span class="token punctuation">(</span></span>event<span class="token punctuation">.</span>nativeEvent<span class="token punctuation">.</span>region<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token function">render<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||
<span class="token keyword">return</span> <RCTMap <span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">}</span> onChange<span class="token operator">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>_onChange<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span>
|
||
MapView<span class="token punctuation">.</span>propTypes <span class="token operator">=</span> <span class="token punctuation">{</span>
|
||
<span class="token comment" spellcheck="true">/**
|
||
* Callback that is called continuously when the user is dragging the map.
|
||
*/</span>
|
||
onRegionChange<span class="token punctuation">:</span> React<span class="token punctuation">.</span>PropTypes<span class="token punctuation">.</span>func<span class="token punctuation">,</span>
|
||
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">;</span></div><h2><a class="anchor" name="styles"></a>Styles <a class="hash-link" href="docs/native-components-ios.html#styles">#</a></h2><p>Since all our native react views are subclasses of <code>UIView</code>, most style attributes will work like you would expect out of the box. Some components will want a default style, however, for example <code>UIDatePicker</code> which is a fixed size. This default style is important for the layout algorithm to work as expected, but we also want to be able to override the default style when using the component. <code>DatePickerIOS</code> does this by wrapping the native component in an extra view, which has flexible styling, and using a fixed style (which is generated with constants passed in from native) on the inner native component:</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// DatePickerIOS.ios.js
|
||
</span>
|
||
import <span class="token punctuation">{</span> UIManager <span class="token punctuation">}</span> from <span class="token string">'react-native'</span><span class="token punctuation">;</span>
|
||
<span class="token keyword">var</span> RCTDatePickerIOSConsts <span class="token operator">=</span> UIManager<span class="token punctuation">.</span>RCTDatePicker<span class="token punctuation">.</span>Constants<span class="token punctuation">;</span>
|
||
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
|
||
render<span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||
<span class="token keyword">return</span> <span class="token punctuation">(</span>
|
||
<View style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>style<span class="token punctuation">}</span><span class="token operator">></span>
|
||
<RCTDatePickerIOS
|
||
ref<span class="token operator">=</span><span class="token punctuation">{</span>DATEPICKER<span class="token punctuation">}</span>
|
||
style<span class="token operator">=</span><span class="token punctuation">{</span>styles<span class="token punctuation">.</span>rkDatePickerIOS<span class="token punctuation">}</span>
|
||
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
|
||
<span class="token operator">/</span><span class="token operator">></span>
|
||
<<span class="token operator">/</span>View<span class="token operator">></span>
|
||
<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||
|
||
<span class="token keyword">var</span> styles <span class="token operator">=</span> StyleSheet<span class="token punctuation">.</span><span class="token function">create<span class="token punctuation">(</span></span><span class="token punctuation">{</span>
|
||
rkDatePickerIOS<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
||
height<span class="token punctuation">:</span> RCTDatePickerIOSConsts<span class="token punctuation">.</span>ComponentHeight<span class="token punctuation">,</span>
|
||
width<span class="token punctuation">:</span> RCTDatePickerIOSConsts<span class="token punctuation">.</span>ComponentWidth<span class="token punctuation">,</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></div><p>The <code>RCTDatePickerIOSConsts</code> constants are exported from native by grabbing the actual frame of the native component like so:</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// RCTDatePickerManager.m
|
||
</span>
|
||
<span class="token operator">-</span> <span class="token punctuation">(</span>NSDictionary <span class="token operator">*</span><span class="token punctuation">)</span>constantsToExport
|
||
<span class="token punctuation">{</span>
|
||
UIDatePicker <span class="token operator">*</span>dp <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">[</span>UIDatePicker alloc<span class="token punctuation">]</span> init<span class="token punctuation">]</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">[</span>dp layoutIfNeeded<span class="token punctuation">]</span><span class="token punctuation">;</span>
|
||
|
||
<span class="token keyword">return</span> @<span class="token punctuation">{</span>
|
||
@<span class="token string">"ComponentHeight"</span><span class="token punctuation">:</span> @<span class="token punctuation">(</span><span class="token function">CGRectGetHeight<span class="token punctuation">(</span></span>dp<span class="token punctuation">.</span>frame<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
|
||
@<span class="token string">"ComponentWidth"</span><span class="token punctuation">:</span> @<span class="token punctuation">(</span><span class="token function">CGRectGetWidth<span class="token punctuation">(</span></span>dp<span class="token punctuation">.</span>frame<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
|
||
@<span class="token string">"DatePickerModes"</span><span class="token punctuation">:</span> @<span class="token punctuation">{</span>
|
||
@<span class="token string">"time"</span><span class="token punctuation">:</span> @<span class="token punctuation">(</span>UIDatePickerModeTime<span class="token punctuation">)</span><span class="token punctuation">,</span>
|
||
@<span class="token string">"date"</span><span class="token punctuation">:</span> @<span class="token punctuation">(</span>UIDatePickerModeDate<span class="token punctuation">)</span><span class="token punctuation">,</span>
|
||
@<span class="token string">"datetime"</span><span class="token punctuation">:</span> @<span class="token punctuation">(</span>UIDatePickerModeDateAndTime<span class="token punctuation">)</span><span class="token punctuation">,</span>
|
||
<span class="token punctuation">}</span>
|
||
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||
<span class="token punctuation">}</span></div><p>This guide covered many of the aspects of bridging over custom native components, but there is even more you might need to consider, such as custom hooks for inserting and laying out subviews. If you want to go even deeper, check out the actual <code>RCTMapManager</code> and other components in the <a href="https://github.com/facebook/react-native/blob/master/React/Views" target="_blank">source code</a>.</p></div><div class="docs-prevnext"><a class="docs-prev" href="docs/native-modules-ios.html#content">← Prev</a><a class="docs-next" href="docs/linking-libraries-ios.html#content">Next →</a></div><p class="edit-page-block">You can <a target="_blank" href="https://github.com/facebook/react-native/blob/master/docs/NativeComponentsIOS.md">edit the content above on GitHub</a> and send us a pull request!</p><div class="survey"><div class="survey-image"></div><p>Recently, we have been working hard to make the documentation better based on your feedback. Your responses to this yes/no style survey will help us gauge whether we moved in the right direction with the improvements. Thank you!</p><center><a class="button" href="https://www.facebook.com/survey?oid=516954245168428">Take Survey</a></center></div></div></section><footer class="wrap"><div class="center">© 2016 Facebook Inc.</div></footer></div><div id="fb-root"></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>
|
||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||
ga('create', 'UA-41298772-2', 'facebook.github.io');
|
||
ga('send', 'pageview');
|
||
|
||
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)
|
||
){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";
|
||
fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
|
||
|
||
docsearch({
|
||
apiKey: '2c98749b4a1e588efec53b2acec13025',
|
||
indexName: 'react-native-versions',
|
||
inputSelector: '#algolia-doc-search',
|
||
algoliaOptions: { facetFilters: [ "tags:0.34" ], hitsPerPage: 5 }
|
||
});
|
||
</script><script src="js/scripts.js"></script></body></html> |