I am writing a react native app that uses the MapView Component. I would like to have annotations with custom images. The React Native Docs for MapView have this to say.
var CustomPinImageMapViewExample = React.createClass({
getInitialState(): CustomPinImageMapViewExampleState {
return {
isFirstLoad: true,
};
},
render() {
if (this.state.isFirstLoad) {
var onRegionChangeComplete = (region) => {
this.setState({
isFirstLoad: false,
annotations: [{
longitude: region.longitude,
latitude: region.latitude,
title: 'Thumbs Up!',
image: require('image!uie_thumb_big'),
}],
});
};
}
return (
<MapView
style={styles.map}
onRegionChangeComplete={onRegionChangeComplete}
region={this.state.mapRegion}
annotations={this.state.annotations}
/>
);
},
});
and tell me that an annotation has an image
property which should be set to a Image.propTypes.source.
annotations [{latitude: number, longitude: number, animateDrop: bool,
title: string, subtitle: string, hasLeftCallout: bool, hasRightCallout:
bool, onLeftCalloutPress: function, onRightCalloutPress: function,
tintColor: string, image: Image.propTypes.source, id: string}]
I tried adding a url
for an image to the image prop on an annotation as you can see here
'use strict';
import React, { Component, Navigator } from 'react-native';
let {
MapView,
StyleSheet,
} = React;
class Map extends Component {
constructor(props) {
super(props);
this.state = {
email : '',
mapRegion : {latitude: 40.734099, longitude: -73.981016, latitudeDelta: 0.3, longitudeDelta: 0.3},
annotations : [
{
longitude: -73.981831,
latitude: 40.733481,
title: 'Pickup',
subtitle: 'a subtitle',
hasLeftCallout: true,
hasRightCallout: true,
animateDrop: true,
},
{
longitude: -73.982282,
latitude: 40.735985,
title: 'Dropoff',
image: 'http://facebook.github.io/react/img/logo_og.png'
}],
};
}
render(){
return (
<MapView
style={styles.map}
annotations={this.state.annotations}
showsUserLocation={true}
/>
);
}
}
const styles = StyleSheet.create({
map: {
height: 300,
margin: 0,
},
});
export default Map;
This did not do anything :(. In addition, I cant even find any mention of an image property in the source for the MapView Component. Which you can look at here.
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* 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.
*
* @providesModule MapView
* @flow
*/
'use strict';
var EdgeInsetsPropType = require('EdgeInsetsPropType');
var NativeMethodsMixin = require('NativeMethodsMixin');
var Platform = require('Platform');
var React = require('React');
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
var View = require('View');
var createReactNativeComponentClass = require('createReactNativeComponentClass');
var deepDiffer = require('deepDiffer');
var insetsDiffer = require('insetsDiffer');
var merge = require('merge');
var requireNativeComponent = require('requireNativeComponent');
type Event = Object;
type MapRegion = {
latitude: number;
longitude: number;
latitudeDelta: number;
longitudeDelta: number;
};
var MapView = React.createClass({
mixins: [NativeMethodsMixin],
checkAnnotationIds: function (annotations: Array<Object>) {
var newAnnotations = annotations.map(function (annotation) {
if (!annotation.id) {
// TODO: add a base64 (or similar) encoder here
annotation.id = encodeURIComponent(JSON.stringify(annotation));
}
return annotation;
});
this.setState({
annotations: newAnnotations
});
},
componentWillMount: function() {
if (this.props.annotations) {
this.checkAnnotationIds(this.props.annotations);
}
},
componentWillReceiveProps: function(nextProps: Object) {
if (nextProps.annotations) {
this.checkAnnotationIds(nextProps.annotations);
}
},
propTypes: {
/**
* Used to style and layout the `MapView`. See `StyleSheet.js` and
* `ViewStylePropTypes.js` for more info.
*/
style: View.propTypes.style,
/**
* If `true` the app will ask for the user's location and focus on it.
* Default value is `false`.
*
* **NOTE**: You need to add NSLocationWhenInUseUsageDescription key in
* Info.plist to enable geolocation, otherwise it is going
* to *fail silently*!
*/
showsUserLocation: React.PropTypes.bool,
/**
* If `false` the user won't be able to pinch/zoom the map.
* Default value is `true`.
*/
zoomEnabled: React.PropTypes.bool,
/**
* 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
*/
rotateEnabled: React.PropTypes.bool,
/**
* 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.
*/
pitchEnabled: React.PropTypes.bool,
/**
* If `false` the user won't be able to change the map region being displayed.
* Default value is `true`.
*/
scrollEnabled: React.PropTypes.bool,
/**
* The map type to be displayed.
*
* - standard: standard road map (default)
* - satellite: satellite view
* - hybrid: satellite view with roads and points of interest overlayed
*/
mapType: React.PropTypes.oneOf([
'standard',
'satellite',
'hybrid',
]),
/**
* The region to be displayed by the map.
*
* The region is defined by the center coordinates and the span of
* coordinates to display.
*/
region: React.PropTypes.shape({
/**
* Coordinates for the center of the map.
*/
latitude: React.PropTypes.number.isRequired,
longitude: React.PropTypes.number.isRequired,
/**
* Distance between the minimun and the maximum latitude/longitude
* to be displayed.
*/
latitudeDelta: React.PropTypes.number.isRequired,
longitudeDelta: React.PropTypes.number.isRequired,
}),
/**
* Map annotations with title/subtitle.
*/
annotations: React.PropTypes.arrayOf(React.PropTypes.shape({
/**
* The location of the annotation.
*/
latitude: React.PropTypes.number.isRequired,
longitude: React.PropTypes.number.isRequired,
/**
* Whether the pin drop should be animated or not
*/
animateDrop: React.PropTypes.bool,
/**
* Annotation title/subtile.
*/
title: React.PropTypes.string,
subtitle: React.PropTypes.string,
/**
* Whether the Annotation has callout buttons.
*/
hasLeftCallout: React.PropTypes.bool,
hasRightCallout: React.PropTypes.bool,
/**
* Event handlers for callout buttons.
*/
onLeftCalloutPress: React.PropTypes.func,
onRightCalloutPress: React.PropTypes.func,
/**
* annotation id
*/
id: React.PropTypes.string
})),
/**
* Maximum size of area that can be displayed.
*/
maxDelta: React.PropTypes.number,
/**
* Minimum size of area that can be displayed.
*/
minDelta: React.PropTypes.number,
/**
* Insets for the map's legal label, originally at bottom left of the map.
* See `EdgeInsetsPropType.js` for more information.
*/
legalLabelInsets: EdgeInsetsPropType,
/**
* Callback that is called continuously when the user is dragging the map.
*/
onRegionChange: React.PropTypes.func,
/**
* Callback that is called once, when the user is done moving the map.
*/
onRegionChangeComplete: React.PropTypes.func,
/**
* Callback that is called once, when the user taps an annotation.
*/
onAnnotationPress: React.PropTypes.func,
},
_onChange: function(event: Event) {
if (event.nativeEvent.continuous) {
this.props.onRegionChange &&
this.props.onRegionChange(event.nativeEvent.region);
} else {
this.props.onRegionChangeComplete &&
this.props.onRegionChangeComplete(event.nativeEvent.region);
}
},
_onPress: function(event: Event) {
if (event.nativeEvent.action === 'annotation-click') {
this.props.onAnnotationPress && this.props.onAnnotationPress(event.nativeEvent.annotation);
}
if (event.nativeEvent.action === 'callout-click') {
if (!this.props.annotations) {
return;
}
// Find the annotation with the id of what has been pressed
for (var i = 0; i < this.props.annotations.length; i++) {
var annotation = this.props.annotations[i];
if (annotation.id === event.nativeEvent.annotationId) {
// Pass the right function
if (event.nativeEvent.side === 'left') {
annotation.onLeftCalloutPress && annotation.onLeftCalloutPress(event.nativeEvent);
} else if (event.nativeEvent.side === 'right') {
annotation.onRightCalloutPress && annotation.onRightCalloutPress(event.nativeEvent);
}
}
}
}
},
render: function() {
return <RCTMap {...this.props} onPress={this._onPress} onChange={this._onChange} />;
},
});
if (Platform.OS === 'android') {
var RCTMap = createReactNativeComponentClass({
validAttributes: merge(
ReactNativeViewAttributes.UIView, {
active: true,
showsUserLocation: true,
zoomEnabled: true,
rotateEnabled: true,
pitchEnabled: true,
scrollEnabled: true,
region: {diff: deepDiffer},
annotations: {diff: deepDiffer},
maxDelta: true,
minDelta: true,
legalLabelInsets: {diff: insetsDiffer},
}
),
uiViewClassName: 'RCTMap',
});
} else {
var RCTMap = requireNativeComponent('RCTMap', MapView, {
nativeOnly: {onChange: true, onPress: true}
});
}
module.exports = MapView;
Here is my packadge.json
for dependency info. Hope somebody can help me give my MapView annotations custom images!
"dependencies": {
"react-native": "0.13 - 0.14",
"react-native-button": "^1.3.1",
"react-native-side-menu": "^0.15.5"
},
"devDependencies": {
"babel-core": "^6.1.2",
"babel-eslint": "^4.1.3",
"babel-loader": "^6.0.0",
"babel-preset-es2015": "^6.0.14",
"babel-preset-react": "^6.0.14",
"babel-preset-stage-1": "^6.1.2",
"eslint": "^1.8.0",
"eslint-loader": "^1.1.1",
"eslint-plugin-react": "^3.6.3",
"react": "^0.14.3",
"react-native-side-menu": "^0.15.5",
"react-native-webpack-server": "^0.8.1",
"react-redux": "3.1",
"redux": "^3.0.4",
"redux-multi": "^0.1.10",
"redux-thunk": "^1.0.0",
"webpack": "^1.12.2",
"webpack-dev-server": "^1.12.1"
},
try...
image: require('./relative/page/to/image.png'),
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With