diff --git a/index.ios.js b/index.ios.js
index 89adacd..97c4764 100644
--- a/index.ios.js
+++ b/index.ios.js
@@ -8,6 +8,10 @@ import {
findNodeHandle
} from 'react-native';
+import cloneDeep from 'lodash/cloneDeep';
+import clone from 'lodash/clone';
+import isEqual from 'lodash/isEqual';
+
const { MapboxGLManager } = NativeModules;
const { mapStyles, userTrackingMode, userLocationVerticalAlignment, unknownResourceCount } = MapboxGLManager;
@@ -206,9 +210,6 @@ class MapView extends Component {
onTap: PropTypes.func,
contentInset: PropTypes.array,
userLocationVerticalAlignment: PropTypes.number,
- onOfflineProgressDidChange: PropTypes.func,
- onOfflineMaxAllowedMapboxTiles: PropTypes.func,
- onOfflineDidRecieveError: PropTypes.func,
onChangeUserTrackingMode: PropTypes.func
};
@@ -231,10 +232,59 @@ class MapView extends Component {
compassIsHidden: false
};
+ componentWillReceiveProps(newProps) {
+ const oldKeys = clone(this._annotations);
+ const itemsToAdd = [];
+ const itemsToRemove = [];
+
+ newProps.annotations.forEach(annotation => {
+ const id = annotation.id;
+ if (!isEqual(this._annotations[id], annotation)) {
+ this._annotations[id] = cloneDeep(annotation);
+ itemsToAdd.push(annotation);
+ }
+ oldKeys[id] = null;
+ });
+
+ for (let key in oldKeys) {
+ if (oldKeys[key]) {
+ delete this._annotations[key];
+ itemsToRemove.push(key);
+ }
+ }
+
+ MapboxGLManager.spliceAnnotations(findNodeHandle(this), false, itemsToRemove, itemsToAdd);
+ }
+
+ _native = null;
+
+ onNativeComponentMount = (ref) => {
+ if (this._native === ref) { return; }
+ this._native = ref;
+
+ MapboxGLManager.spliceAnnotations(findNodeHandle(this), true, [], this.props.annotations);
+
+ let annotations = this.props.annotations.reduce((acc, annotation) => {
+ acc[annotation.id] = cloneDeep(annotation);
+ return acc;
+ }, {});
+
+ this._annotations = annotations;
+ };
+
+ setNativeProps(nativeProps) {
+ this._native && this._native.setNativeProps(nativeProps);
+ }
+
+ componentWillUnmount() {
+ this._native = null;
+ }
+
render() {
return (
+ onChangeUserTrackingMode={this._onChangeUserTrackingMode}
+ />
);
}
}
diff --git a/ios/RCTMapboxGL/RCTMapboxGL.h b/ios/RCTMapboxGL/RCTMapboxGL.h
index 84a0e7c..a484bfc 100644
--- a/ios/RCTMapboxGL/RCTMapboxGL.h
+++ b/ios/RCTMapboxGL/RCTMapboxGL.h
@@ -40,7 +40,7 @@
- (void)selectAnnotation:(NSString*)selectedId animated:(BOOL)animated;
// Annotation management
-- (void)addAnnotation:(NSObject *)annotation;
+- (void)upsertAnnotation:(NSObject *)annotation;
- (void)removeAnnotation:(NSString*)selectedIdentifier;
- (void)removeAllAnnotations;
diff --git a/ios/RCTMapboxGL/RCTMapboxGL.m b/ios/RCTMapboxGL/RCTMapboxGL.m
index 2a71392..035fff3 100644
--- a/ios/RCTMapboxGL/RCTMapboxGL.m
+++ b/ios/RCTMapboxGL/RCTMapboxGL.m
@@ -101,7 +101,9 @@
_isChangingUserTracking = YES;
_map.userTrackingMode = _userTrackingMode;
_isChangingUserTracking = NO;
- [_map addAnnotations:[_annotations allValues]];
+ for (NSString * annotationId in _annotations) {
+ [_map addAnnotation:_annotations[annotationId]];
+ }
[self addSubview:_map];
[self layoutSubviews];
@@ -122,14 +124,19 @@
// Annotation management
-- (void)addAnnotation:(RCTMGLAnnotation *) annotation {
+- (void)upsertAnnotation:(RCTMGLAnnotation *) annotation {
NSString * identifier = [annotation id];
if (!identifier || [identifier length] == 0) {
RCTLogError(@"field `id` is required on all annotations");
return;
}
+
+ RCTMGLAnnotation * oldAnnotation = [_annotations objectForKey:identifier];
[_annotations setObject:annotation forKey:identifier];
[_map addAnnotation:annotation];
+ if (oldAnnotation) {
+ [_map removeAnnotation:oldAnnotation];
+ }
}
- (void)removeAnnotation:(NSString*)selectedIdentifier
diff --git a/ios/RCTMapboxGL/RCTMapboxGLManager.m b/ios/RCTMapboxGL/RCTMapboxGLManager.m
index da5dde9..b7dac2b 100644
--- a/ios/RCTMapboxGL/RCTMapboxGLManager.m
+++ b/ios/RCTMapboxGL/RCTMapboxGLManager.m
@@ -73,23 +73,6 @@ RCT_CUSTOM_VIEW_PROPERTY(contentInset, UIEdgeInsetsMake, RCTMapboxGL)
view.contentInset = inset;
}
-RCT_CUSTOM_VIEW_PROPERTY(annotations, CLLocationCoordinate2D, RCTMapboxGL)
-{
- if ([json isKindOfClass:[NSArray class]]) {
- [view removeAllAnnotations];
-
- id annotationObject;
- NSEnumerator *enumerator = [json objectEnumerator];
-
- while (annotationObject = [enumerator nextObject]) {
- CLLocationCoordinate2D coordinate = [RCTConvert CLLocationCoordinate2D:annotationObject];
- if (CLLocationCoordinate2DIsValid(coordinate)){
- [view addAnnotation:convertToMGLAnnotation(annotationObject)];
- }
- }
- }
-}
-
// Constants
- (NSDictionary *)constantsToExport
@@ -306,6 +289,28 @@ RCT_EXPORT_METHOD(removePack:(NSString*)packName
// View methods
+RCT_EXPORT_METHOD(spliceAnnotations:(nonnull NSNumber *)reactTag
+ deleteAll:(BOOL)deleteAll
+ toDelete:(nonnull NSArray *)toDelete
+ toAdd:(nonnull NSArray *)toAdd)
+{
+ [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) {
+ RCTMapboxGL *mapView = viewRegistry[reactTag];
+
+ if (deleteAll) {
+ [mapView removeAllAnnotations];
+ } else {
+ for (NSString * key in toDelete) {
+ [mapView removeAnnotation:key];
+ }
+ }
+
+ for (NSObject * annotationObject in toAdd) {
+ [mapView upsertAnnotation:convertToMGLAnnotation(annotationObject)];
+ }
+ }];
+}
+
RCT_EXPORT_METHOD(getCenterCoordinateZoomLevel:(nonnull NSNumber *)reactTag
callback:(RCTResponseSenderBlock)callback)
{
diff --git a/package.json b/package.json
index 6535881..e06b8a8 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,7 @@
"eslint-plugin-react": "^3.11.3"
},
"dependencies": {
- "babel-eslint": "^4.1.6"
+ "babel-eslint": "^4.1.6",
+ "lodash": "^4.13.1"
}
}