Permalink
Browse files

fix duplicate symbols error in the Creating Native UI Component docs

Summary:
When creating Native UI Component per docs, it results in duplicate symbols error as explained in issue #12404

Instead of using RCT prefix, it is suggested to use RN prefix to avoid any duplicate symbols.
Closes #12523

Differential Revision: D4608532

Pulled By: hramos

fbshipit-source-id: 353cfee4bf2cea30706863af51cabe11e9394222
  • Loading branch information...
hramos authored and facebook-github-bot committed Feb 24, 2017
1 parent 4b26ebd commit fab09922cdaae97f960a3fa80ceb8549955243da
Showing with 26 additions and 24 deletions.
  1. +26 −24 docs/NativeComponentsIOS.md
@@ -25,15 +25,15 @@ Vending a view is simple:
- Implement the `-(UIView *)view` method.
```objective-c
// RCTMapManager.m
// RNTMapManager.m
#import <MapKit/MapKit.h>
#import <React/RCTViewManager.h>
@interface RCTMapManager : RCTViewManager
@interface RNTMapManager : RCTViewManager
@end
@implementation RCTMapManager
@implementation RNTMapManager
RCT_EXPORT_MODULE()
@@ -46,15 +46,17 @@ RCT_EXPORT_MODULE()
```
**Note:** Do not attempt to set the `frame` or `backgroundColor` properties on the `UIView` instance that you vend through the `-view` 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 `UIView` instance you want to style in another `UIView` and return the wrapper `UIView` instead. See [Issue 2948](https://github.com/facebook/react-native/issues/2948) for more context.
> In the example above, we prefixed our class name with `RNT`. Prefixes are used to avoid name collisions with other frameworks. Apple frameworks use two-letter prefixes, and React Native uses `RCT` as a prefix. In order to avoid name collisions, we recommend using a three-letter prefix other than `RCT` in your own classes.
Then you just need a little bit of JavaScript to make this a usable React component:
```javascript
// MapView.js
import { requireNativeComponent } from 'react-native';
// requireNativeComponent automatically resolves this to "RCTMapManager"
module.exports = requireNativeComponent('RCTMap', null);
// requireNativeComponent automatically resolves this to "RNTMapManager"
module.exports = requireNativeComponent('RNTMap', null);
```
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 :(
@@ -64,7 +66,7 @@ This is now a fully-functioning native map view component in JavaScript, complet
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:
```objective-c
// RCTMapManager.m
// RNTMapManager.m
RCT_EXPORT_VIEW_PROPERTY(pitchEnabled, BOOL)
```
@@ -86,7 +88,7 @@ import { requireNativeComponent } from 'react-native';
class MapView extends React.Component {
render() {
return <RCTMap {...this.props} />;
return <RNTMap {...this.props} />;
}
}
@@ -101,7 +103,7 @@ MapView.propTypes = {
pitchEnabled: React.PropTypes.bool,
};
var RCTMap = requireNativeComponent('RCTMap', MapView);
var RNTMap = requireNativeComponent('RNTMap', MapView);
module.exports = MapView;
```
@@ -111,8 +113,8 @@ Now we have a nicely documented wrapper component that is easy to work with. No
Next, let's add the more complex `region` prop. We start by adding the native code:
```objective-c
// RCTMapManager.m
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
// RNTMapManager.m
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RNTMap)
{
[view setRegion:json ? [RCTConvert MKCoordinateRegion:json] : defaultView.region animated:YES];
}
@@ -224,61 +226,61 @@ var RCTSwitch = requireNativeComponent('RCTSwitch', Switch, {
## Events
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 `RCTMapManager`, 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):
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 `RNTMapManager`, 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):
```objective-c
// RCTMap.h
// RNTMap.h
#import <MapKit/MapKit.h>
#import <React/RCTComponent.h>
@interface RCTMap: MKMapView
@interface RNTMap: MKMapView
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
@end
```
```objective-c
// RCTMap.m
// RNTMap.m
#import "RCTMap.h"
#import "RNTMap.h"
@implementation RCTMap
@implementation RNTMap
@end
```
```objective-c
// RCTMapManager.m
// RNTMapManager.m
#import "RCTMapManager.h"
#import "RNTMapManager.h"
#import <MapKit/MapKit.h>
#import "RCTMap.h"
#import "RNTMap.h"
#import <React/UIView+React.h>
@interface RCTMapManager() <MKMapViewDelegate>
@interface RNTMapManager() <MKMapViewDelegate>
@end
@implementation RCTMapManager
@implementation RNTMapManager
RCT_EXPORT_MODULE()
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
- (UIView *)view
{
RCTMap *map = [RCTMap new];
RNTMap *map = [RNTMap new];
map.delegate = self;
return map;
}
#pragma mark MKMapViewDelegate
- (void)mapView:(RCTMap *)mapView regionDidChangeAnimated:(BOOL)animated
- (void)mapView:(RNTMap *)mapView regionDidChangeAnimated:(BOOL)animated
{
if (!mapView.onChange) {
return;
@@ -312,7 +314,7 @@ class MapView extends React.Component {
this.props.onRegionChange(event.nativeEvent.region);
}
render() {
return <RCTMap {...this.props} onChange={this._onChange} />;
return <RNTMap {...this.props} onChange={this._onChange} />;
}
}
MapView.propTypes = {

0 comments on commit fab0992

Please sign in to comment.