react-native-maps 1.21.0-alpha.133 → 1.21.0-alpha.135

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -142,6 +142,9 @@ public class RNMapsMapViewManagerDelegate<T extends View, U extends BaseViewMana
142
142
  case "userInterfaceStyle":
143
143
  mViewManager.setUserInterfaceStyle(view, (String) value);
144
144
  break;
145
+ case "customMapStyleString":
146
+ mViewManager.setCustomMapStyleString(view, value == null ? null : (String) value);
147
+ break;
145
148
  case "userLocationAnnotationTitle":
146
149
  mViewManager.setUserLocationAnnotationTitle(view, value == null ? null : (String) value);
147
150
  break;
@@ -53,6 +53,7 @@ public interface RNMapsMapViewManagerInterface<T extends View> {
53
53
  void setTintColor(T view, @Nullable Integer value);
54
54
  void setToolbarEnabled(T view, boolean value);
55
55
  void setUserInterfaceStyle(T view, @Nullable String value);
56
+ void setCustomMapStyleString(T view, @Nullable String value);
56
57
  void setUserLocationAnnotationTitle(T view, @Nullable String value);
57
58
  void setUserLocationCalloutEnabled(T view, boolean value);
58
59
  void setUserLocationFastestInterval(T view, int value);
@@ -461,6 +461,11 @@ public class MapViewManager extends ViewGroupManager<MapView> implements RNMapsM
461
461
  // do nothing (initialProp)
462
462
  }
463
463
 
464
+ @Override
465
+ public void setCustomMapStyleString(MapView view, @Nullable String value) {
466
+ view.setMapStyle(value);
467
+ }
468
+
464
469
  @Override
465
470
  public void setUserLocationAnnotationTitle(MapView view, @Nullable String value) {
466
471
  // not supported
@@ -66,6 +66,7 @@ RNMapsGoogleMapViewProps::RNMapsGoogleMapViewProps(
66
66
  showsTraffic(convertRawProp(context, rawProps, "showsTraffic", sourceProps.showsTraffic, {false})),
67
67
  showsUserLocation(convertRawProp(context, rawProps, "showsUserLocation", sourceProps.showsUserLocation, {false})),
68
68
  userInterfaceStyle(convertRawProp(context, rawProps, "userInterfaceStyle", sourceProps.userInterfaceStyle, {RNMapsGoogleMapViewUserInterfaceStyle::System})),
69
+ customMapStyleString(convertRawProp(context, rawProps, "customMapStyleString", sourceProps.customMapStyleString, {})),
69
70
  userLocationCalloutEnabled(convertRawProp(context, rawProps, "userLocationCalloutEnabled", sourceProps.userLocationCalloutEnabled, {false})),
70
71
  userLocationFastestInterval(convertRawProp(context, rawProps, "userLocationFastestInterval", sourceProps.userLocationFastestInterval, {0})),
71
72
  userLocationPriority(convertRawProp(context, rawProps, "userLocationPriority", sourceProps.userLocationPriority, {RNMapsGoogleMapViewUserLocationPriority::High})),
@@ -130,6 +131,7 @@ RNMapsMapViewProps::RNMapsMapViewProps(
130
131
  tintColor(convertRawProp(context, rawProps, "tintColor", sourceProps.tintColor, {})),
131
132
  toolbarEnabled(convertRawProp(context, rawProps, "toolbarEnabled", sourceProps.toolbarEnabled, {true})),
132
133
  userInterfaceStyle(convertRawProp(context, rawProps, "userInterfaceStyle", sourceProps.userInterfaceStyle, {RNMapsMapViewUserInterfaceStyle::System})),
134
+ customMapStyleString(convertRawProp(context, rawProps, "customMapStyleString", sourceProps.customMapStyleString, {})),
133
135
  userLocationAnnotationTitle(convertRawProp(context, rawProps, "userLocationAnnotationTitle", sourceProps.userLocationAnnotationTitle, {})),
134
136
  userLocationCalloutEnabled(convertRawProp(context, rawProps, "userLocationCalloutEnabled", sourceProps.userLocationCalloutEnabled, {false})),
135
137
  userLocationFastestInterval(convertRawProp(context, rawProps, "userLocationFastestInterval", sourceProps.userLocationFastestInterval, {5000})),
@@ -391,6 +391,7 @@ class RNMapsGoogleMapViewProps final : public ViewProps {
391
391
  bool showsTraffic{false};
392
392
  bool showsUserLocation{false};
393
393
  RNMapsGoogleMapViewUserInterfaceStyle userInterfaceStyle{RNMapsGoogleMapViewUserInterfaceStyle::System};
394
+ std::string customMapStyleString{};
394
395
  bool userLocationCalloutEnabled{false};
395
396
  int userLocationFastestInterval{0};
396
397
  RNMapsGoogleMapViewUserLocationPriority userLocationPriority{RNMapsGoogleMapViewUserLocationPriority::High};
@@ -917,6 +918,7 @@ class RNMapsMapViewProps final : public ViewProps {
917
918
  SharedColor tintColor{};
918
919
  bool toolbarEnabled{true};
919
920
  RNMapsMapViewUserInterfaceStyle userInterfaceStyle{RNMapsMapViewUserInterfaceStyle::System};
921
+ std::string customMapStyleString{};
920
922
  std::string userLocationAnnotationTitle{};
921
923
  bool userLocationCalloutEnabled{false};
922
924
  int userLocationFastestInterval{5000};
@@ -666,8 +666,7 @@ id regionAsJSON(MKCoordinateRegion region) {
666
666
  if (!style) {
667
667
  NSLog(@"The style definition could not be loaded: %@", error);
668
668
  }
669
-
670
- self.mapStyle = style;
669
+ [self setMapStyle:style];
671
670
  }
672
671
 
673
672
  - (BOOL)showsCompass {
@@ -14,6 +14,7 @@
14
14
  @interface AIRGoogleMapManager : RCTViewManager
15
15
 
16
16
  @property (nonatomic, strong) NSString* googleMapId;
17
+ @property (nonatomic, strong) NSString* customMapStyle;
17
18
  @property (nonatomic) BOOL zoomTapEnabled;
18
19
  @property (nonatomic, strong) UIColor* backgroundColor;
19
20
  @property (nonatomic, strong) GMSCameraPosition* camera;
@@ -30,7 +30,7 @@ static NSString *const RCTMapViewKey = @"MapView";
30
30
 
31
31
  @interface AIRGoogleMapManager() <GMSMapViewDelegate>
32
32
  {
33
- BOOL didCallOnMapReady;
33
+ BOOL didCallOnMapReady;
34
34
  }
35
35
  @end
36
36
 
@@ -40,37 +40,40 @@ RCT_EXPORT_MODULE()
40
40
 
41
41
  - (UIView *)view
42
42
  {
43
-
44
- if (self.initialProps){
45
- if (self.initialProps[@"googleMapId"]){
46
- _googleMapId = self.initialProps[@"googleMapId"];
47
- }
48
- if (self.initialProps[@"zoomTapEnabled"]){
49
- _zoomTapEnabled = self.initialProps[@"zoomTapEnabled"];
50
- }
51
- if (self.initialProps[@"loadingBackgroundColor"]){
52
- _backgroundColor = [RCTConvert UIColor:self.initialProps[@"loadingBackgroundColor"]];
53
- }
54
- if (self.initialProps[@"initialCamera"]){
55
- _camera = [RCTConvert GMSCameraPositionWithDefaults:self.initialProps[@"initialCamera"] existingCamera:nil];
56
- }
57
- }
58
- AIRGoogleMap *map = [[AIRGoogleMap alloc] initWithMapId:self.googleMapId initialCamera:self.camera backgroundColor:self.backgroundColor andZoomTapEnabled:self.zoomTapEnabled];
59
- map.bridge = self.bridge;
60
- map.delegate = self;
61
- map.isAccessibilityElement = NO;
62
- map.accessibilityElementsHidden = NO;
63
- map.settings.consumesGesturesInView = NO;
64
-
65
- UIPanGestureRecognizer *drag = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleMapDrag:)];
66
- [drag setMinimumNumberOfTouches:1];
67
- [drag setMaximumNumberOfTouches:1];
68
- [map addGestureRecognizer:drag];
69
-
70
- UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleMapDrag:)];
71
- [map addGestureRecognizer:pinch];
72
-
73
- return map;
43
+
44
+ if (self.initialProps){
45
+ if (self.initialProps[@"googleMapId"]){
46
+ _googleMapId = self.initialProps[@"googleMapId"];
47
+ }
48
+ if (self.initialProps[@"zoomTapEnabled"]){
49
+ _zoomTapEnabled = self.initialProps[@"zoomTapEnabled"];
50
+ }
51
+ if (self.initialProps[@"loadingBackgroundColor"]){
52
+ _backgroundColor = [RCTConvert UIColor:self.initialProps[@"loadingBackgroundColor"]];
53
+ }
54
+ if (self.initialProps[@"initialCamera"]){
55
+ _camera = [RCTConvert GMSCameraPositionWithDefaults:self.initialProps[@"initialCamera"] existingCamera:nil];
56
+ }
57
+ }
58
+ AIRGoogleMap *map = [[AIRGoogleMap alloc] initWithMapId:self.googleMapId initialCamera:self.camera backgroundColor:self.backgroundColor andZoomTapEnabled:self.zoomTapEnabled];
59
+ map.bridge = self.bridge;
60
+ map.delegate = self;
61
+ map.isAccessibilityElement = NO;
62
+ map.accessibilityElementsHidden = NO;
63
+ map.settings.consumesGesturesInView = NO;
64
+ if (self.customMapStyle != nil){
65
+ map.customMapStyleString = self.customMapStyle;
66
+ }
67
+
68
+ UIPanGestureRecognizer *drag = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleMapDrag:)];
69
+ [drag setMinimumNumberOfTouches:1];
70
+ [drag setMaximumNumberOfTouches:1];
71
+ [map addGestureRecognizer:drag];
72
+
73
+ UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleMapDrag:)];
74
+ [map addGestureRecognizer:pinch];
75
+
76
+ return map;
74
77
  }
75
78
 
76
79
  RCT_EXPORT_VIEW_PROPERTY(isAccessibilityElement, BOOL)
@@ -130,14 +133,14 @@ RCT_EXPORT_METHOD(getCamera:(nonnull NSNumber *)reactTag
130
133
  } else {
131
134
  AIRGoogleMap *mapView = (AIRGoogleMap *)view;
132
135
  resolve(@{
133
- @"center": @{
134
- @"latitude": @(mapView.camera.target.latitude),
135
- @"longitude": @(mapView.camera.target.longitude),
136
- },
137
- @"pitch": @(mapView.camera.viewingAngle),
138
- @"heading": @(mapView.camera.bearing),
139
- @"zoom": @(mapView.camera.zoom),
140
- });
136
+ @"center": @{
137
+ @"latitude": @(mapView.camera.target.latitude),
138
+ @"longitude": @(mapView.camera.target.longitude),
139
+ },
140
+ @"pitch": @(mapView.camera.viewingAngle),
141
+ @"heading": @(mapView.camera.bearing),
142
+ @"zoom": @(mapView.camera.zoom),
143
+ });
141
144
  }
142
145
  }];
143
146
  }
@@ -181,36 +184,36 @@ RCT_EXPORT_METHOD(animateToRegion:(nonnull NSNumber *)reactTag
181
184
  withRegion:(MKCoordinateRegion)region
182
185
  withDuration:(CGFloat)duration)
183
186
  {
184
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
185
- id view = viewRegistry[reactTag];
186
- if (![view isKindOfClass:[AIRGoogleMap class]]) {
187
- RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
188
- } else {
189
- // Core Animation must be used to control the animation's duration
190
- // See http://stackoverflow.com/a/15663039/171744
191
- [CATransaction begin];
192
- [CATransaction setAnimationDuration:duration/1000];
193
- AIRGoogleMap *mapView = (AIRGoogleMap *)view;
194
- GMSCameraPosition *camera = [AIRGoogleMap makeGMSCameraPositionFromMap:mapView andMKCoordinateRegion:region];
195
- [mapView animateToCameraPosition:camera];
196
- [CATransaction commit];
197
- }
198
- }];
187
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
188
+ id view = viewRegistry[reactTag];
189
+ if (![view isKindOfClass:[AIRGoogleMap class]]) {
190
+ RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
191
+ } else {
192
+ // Core Animation must be used to control the animation's duration
193
+ // See http://stackoverflow.com/a/15663039/171744
194
+ [CATransaction begin];
195
+ [CATransaction setAnimationDuration:duration/1000];
196
+ AIRGoogleMap *mapView = (AIRGoogleMap *)view;
197
+ GMSCameraPosition *camera = [AIRGoogleMap makeGMSCameraPositionFromMap:mapView andMKCoordinateRegion:region];
198
+ [mapView animateToCameraPosition:camera];
199
+ [CATransaction commit];
200
+ }
201
+ }];
199
202
  }
200
203
 
201
204
  RCT_EXPORT_METHOD(fitToElements:(nonnull NSNumber *)reactTag
202
205
  edgePadding:(nonnull NSDictionary *)edgePadding
203
206
  animated:(BOOL)animated)
204
207
  {
205
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
206
- id view = viewRegistry[reactTag];
207
- if (![view isKindOfClass:[AIRGoogleMap class]]) {
208
- RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
209
- } else {
210
- AIRGoogleMap *mapView = (AIRGoogleMap *)view;
211
- [mapView fitToElementsWithEdgePadding:edgePadding animated:animated];
212
- }
213
- }];
208
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
209
+ id view = viewRegistry[reactTag];
210
+ if (![view isKindOfClass:[AIRGoogleMap class]]) {
211
+ RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
212
+ } else {
213
+ AIRGoogleMap *mapView = (AIRGoogleMap *)view;
214
+ [mapView fitToElementsWithEdgePadding:edgePadding animated:animated];
215
+ }
216
+ }];
214
217
  }
215
218
 
216
219
  RCT_EXPORT_METHOD(fitToSuppliedMarkers:(nonnull NSNumber *)reactTag
@@ -218,15 +221,15 @@ RCT_EXPORT_METHOD(fitToSuppliedMarkers:(nonnull NSNumber *)reactTag
218
221
  edgePadding:(nonnull NSDictionary *)edgePadding
219
222
  animated:(BOOL)animated)
220
223
  {
221
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
222
- id view = viewRegistry[reactTag];
223
- if (![view isKindOfClass:[AIRGoogleMap class]]) {
224
- RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
225
- } else {
226
- AIRGoogleMap *mapView = (AIRGoogleMap *)view;
227
- [mapView fitToSuppliedMarkers:markers withEdgePadding:edgePadding animated:animated];
228
- }
229
- }];
224
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
225
+ id view = viewRegistry[reactTag];
226
+ if (![view isKindOfClass:[AIRGoogleMap class]]) {
227
+ RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
228
+ } else {
229
+ AIRGoogleMap *mapView = (AIRGoogleMap *)view;
230
+ [mapView fitToSuppliedMarkers:markers withEdgePadding:edgePadding animated:animated];
231
+ }
232
+ }];
230
233
  }
231
234
 
232
235
  RCT_EXPORT_METHOD(fitToCoordinates:(nonnull NSNumber *)reactTag
@@ -234,15 +237,15 @@ RCT_EXPORT_METHOD(fitToCoordinates:(nonnull NSNumber *)reactTag
234
237
  edgePadding:(nonnull NSDictionary *)edgePadding
235
238
  animated:(BOOL)animated)
236
239
  {
237
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
238
- id view = viewRegistry[reactTag];
239
- if (![view isKindOfClass:[AIRGoogleMap class]]) {
240
- RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
241
- } else {
242
- AIRGoogleMap *mapView = (AIRGoogleMap *)view;
243
- [mapView fitToCoordinates:coordinates withEdgePadding:edgePadding animated:animated];
244
- }
245
- }];
240
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
241
+ id view = viewRegistry[reactTag];
242
+ if (![view isKindOfClass:[AIRGoogleMap class]]) {
243
+ RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
244
+ } else {
245
+ AIRGoogleMap *mapView = (AIRGoogleMap *)view;
246
+ [mapView fitToCoordinates:coordinates withEdgePadding:edgePadding animated:animated];
247
+ }
248
+ }];
246
249
  }
247
250
 
248
251
  RCT_EXPORT_METHOD(takeSnapshot:(nonnull NSNumber *)reactTag
@@ -254,54 +257,54 @@ RCT_EXPORT_METHOD(takeSnapshot:(nonnull NSNumber *)reactTag
254
257
  result:(nonnull NSString *)result
255
258
  withCallback:(RCTPromiseResolveBlock)callback)
256
259
  {
257
- NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
258
- NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.%@", timeStamp, format];
259
- NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent: pathComponent];
260
-
261
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
262
- id view = viewRegistry[reactTag];
263
- if (![view isKindOfClass:[AIRGoogleMap class]]) {
264
- RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view);
265
- } else {
266
- AIRGoogleMap *mapView = (AIRGoogleMap *)view;
267
- NSMutableDictionary* config = [NSMutableDictionary new];
268
-
269
- [mapView takeSnapshotWithConfig:config success:callback error:^(NSString *code, NSString *message, NSError *error) {
270
- callback(@[error]);
271
- }];
272
-
273
- [config setObject:width forKey:@"width"];
274
- [config setObject:height forKey:@"height"];
275
- [config setObject:format forKey:@"format"];
276
- [config setObject:quality forKey:@"quality"];
277
- [config setObject:result forKey:@"result"];
278
- [config setObject:filePath forKey:@"filePath"];
279
-
280
- // TODO: currently we are ignoring width, height, region
281
-
282
- UIGraphicsBeginImageContextWithOptions(mapView.frame.size, YES, 0.0f);
283
- [mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
284
- UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
285
-
286
- NSData *data;
287
- if ([format isEqualToString:@"png"]) {
288
- data = UIImagePNGRepresentation(image);
289
-
290
- }
291
- else if([format isEqualToString:@"jpg"]) {
292
- data = UIImageJPEGRepresentation(image, quality.floatValue);
293
- }
294
-
295
- if ([result isEqualToString:@"file"]) {
296
- [data writeToFile:filePath atomically:YES];
297
- callback(@[[NSNull null], filePath]);
298
- }
299
- else if ([result isEqualToString:@"base64"]) {
300
- callback(@[[NSNull null], [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]]);
260
+ NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
261
+ NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.%@", timeStamp, format];
262
+ NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent: pathComponent];
263
+
264
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
265
+ id view = viewRegistry[reactTag];
266
+ if (![view isKindOfClass:[AIRGoogleMap class]]) {
267
+ RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view);
268
+ } else {
269
+ AIRGoogleMap *mapView = (AIRGoogleMap *)view;
270
+ NSMutableDictionary* config = [NSMutableDictionary new];
271
+
272
+ [mapView takeSnapshotWithConfig:config success:callback error:^(NSString *code, NSString *message, NSError *error) {
273
+ callback(@[error]);
274
+ }];
275
+
276
+ [config setObject:width forKey:@"width"];
277
+ [config setObject:height forKey:@"height"];
278
+ [config setObject:format forKey:@"format"];
279
+ [config setObject:quality forKey:@"quality"];
280
+ [config setObject:result forKey:@"result"];
281
+ [config setObject:filePath forKey:@"filePath"];
282
+
283
+ // TODO: currently we are ignoring width, height, region
284
+
285
+ UIGraphicsBeginImageContextWithOptions(mapView.frame.size, YES, 0.0f);
286
+ [mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
287
+ UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
288
+
289
+ NSData *data;
290
+ if ([format isEqualToString:@"png"]) {
291
+ data = UIImagePNGRepresentation(image);
292
+
293
+ }
294
+ else if([format isEqualToString:@"jpg"]) {
295
+ data = UIImageJPEGRepresentation(image, quality.floatValue);
296
+ }
297
+
298
+ if ([result isEqualToString:@"file"]) {
299
+ [data writeToFile:filePath atomically:YES];
300
+ callback(@[[NSNull null], filePath]);
301
+ }
302
+ else if ([result isEqualToString:@"base64"]) {
303
+ callback(@[[NSNull null], [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]]);
304
+ }
301
305
  }
302
- }
303
- UIGraphicsEndImageContext();
304
- }];
306
+ UIGraphicsEndImageContext();
307
+ }];
305
308
  }
306
309
 
307
310
  RCT_EXPORT_METHOD(pointForCoordinate:(nonnull NSNumber *)reactTag
@@ -309,21 +312,21 @@ RCT_EXPORT_METHOD(pointForCoordinate:(nonnull NSNumber *)reactTag
309
312
  resolver: (RCTPromiseResolveBlock)resolve
310
313
  rejecter:(RCTPromiseRejectBlock)reject)
311
314
  {
312
- CLLocationCoordinate2D coord =
313
- CLLocationCoordinate2DMake(
314
- [coordinate[@"latitude"] doubleValue],
315
- [coordinate[@"longitude"] doubleValue]
316
- );
317
-
318
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
319
- id view = viewRegistry[reactTag];
320
- if (![view isKindOfClass:[AIRGoogleMap class]]) {
321
- RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view);
322
- } else {
323
- AIRGoogleMap *mapView = (AIRGoogleMap *)view;
324
- resolve([mapView getPointForCoordinates:coord]);
325
- }
326
- }];
315
+ CLLocationCoordinate2D coord =
316
+ CLLocationCoordinate2DMake(
317
+ [coordinate[@"latitude"] doubleValue],
318
+ [coordinate[@"longitude"] doubleValue]
319
+ );
320
+
321
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
322
+ id view = viewRegistry[reactTag];
323
+ if (![view isKindOfClass:[AIRGoogleMap class]]) {
324
+ RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view);
325
+ } else {
326
+ AIRGoogleMap *mapView = (AIRGoogleMap *)view;
327
+ resolve([mapView getPointForCoordinates:coord]);
328
+ }
329
+ }];
327
330
  }
328
331
 
329
332
  RCT_EXPORT_METHOD(coordinateForPoint:(nonnull NSNumber *)reactTag
@@ -331,20 +334,20 @@ RCT_EXPORT_METHOD(coordinateForPoint:(nonnull NSNumber *)reactTag
331
334
  resolver: (RCTPromiseResolveBlock)resolve
332
335
  rejecter:(RCTPromiseRejectBlock)reject)
333
336
  {
334
- CGPoint pt = CGPointMake(
335
- [point[@"x"] doubleValue],
336
- [point[@"y"] doubleValue]
337
- );
338
-
339
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
340
- id view = viewRegistry[reactTag];
341
- if (![view isKindOfClass:[AIRGoogleMap class]]) {
342
- RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view);
343
- } else {
344
- AIRGoogleMap *mapView = (AIRGoogleMap *)view;
345
- resolve([view getCoordinatesForPoint:pt]);
346
- }
347
- }];
337
+ CGPoint pt = CGPointMake(
338
+ [point[@"x"] doubleValue],
339
+ [point[@"y"] doubleValue]
340
+ );
341
+
342
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
343
+ id view = viewRegistry[reactTag];
344
+ if (![view isKindOfClass:[AIRGoogleMap class]]) {
345
+ RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view);
346
+ } else {
347
+ AIRGoogleMap *mapView = (AIRGoogleMap *)view;
348
+ resolve([view getCoordinatesForPoint:pt]);
349
+ }
350
+ }];
348
351
  }
349
352
 
350
353
  RCT_EXPORT_METHOD(getMarkersFrames:(nonnull NSNumber *)reactTag
@@ -367,140 +370,140 @@ RCT_EXPORT_METHOD(getMapBoundaries:(nonnull NSNumber *)reactTag
367
370
  resolver:(RCTPromiseResolveBlock)resolve
368
371
  rejecter:(RCTPromiseRejectBlock)reject)
369
372
  {
370
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
371
- id view = viewRegistry[reactTag];
372
- if (![view isKindOfClass:[AIRGoogleMap class]]) {
373
- RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
374
- } else {
375
- resolve([view getMapBoundaries]);
376
- }
377
- }];
373
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
374
+ id view = viewRegistry[reactTag];
375
+ if (![view isKindOfClass:[AIRGoogleMap class]]) {
376
+ RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
377
+ } else {
378
+ resolve([view getMapBoundaries]);
379
+ }
380
+ }];
378
381
  }
379
382
 
380
383
  RCT_EXPORT_METHOD(setMapBoundaries:(nonnull NSNumber *)reactTag
381
384
  northEast:(CLLocationCoordinate2D)northEast
382
385
  southWest:(CLLocationCoordinate2D)southWest)
383
386
  {
384
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
385
- id view = viewRegistry[reactTag];
386
- if (![view isKindOfClass:[AIRGoogleMap class]]) {
387
- RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
388
- } else {
389
- AIRGoogleMap *mapView = (AIRGoogleMap *)view;
390
-
391
- GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:northEast coordinate:southWest];
392
-
393
- mapView.cameraTargetBounds = bounds;
394
- }
395
- }];
387
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
388
+ id view = viewRegistry[reactTag];
389
+ if (![view isKindOfClass:[AIRGoogleMap class]]) {
390
+ RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
391
+ } else {
392
+ AIRGoogleMap *mapView = (AIRGoogleMap *)view;
393
+
394
+ GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:northEast coordinate:southWest];
395
+
396
+ mapView.cameraTargetBounds = bounds;
397
+ }
398
+ }];
396
399
  }
397
400
 
398
401
  RCT_EXPORT_METHOD(setIndoorActiveLevelIndex:(nonnull NSNumber *)reactTag
399
402
  levelIndex:(NSInteger) levelIndex)
400
403
  {
401
- [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
402
- id view = viewRegistry[reactTag];
403
- if (![view isKindOfClass:[AIRGoogleMap class]]) {
404
- RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
405
- } else {
406
- AIRGoogleMap *mapView = (AIRGoogleMap *)view;
407
- if (!mapView.indoorDisplay) {
408
- return;
409
- }
410
- if ( levelIndex < [mapView.indoorDisplay.activeBuilding.levels count]) {
411
- mapView.indoorDisplay.activeLevel = mapView.indoorDisplay.activeBuilding.levels[levelIndex];
412
- }
413
- }
414
- }];
415
- }
404
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
405
+ id view = viewRegistry[reactTag];
406
+ if (![view isKindOfClass:[AIRGoogleMap class]]) {
407
+ RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view);
408
+ } else {
409
+ AIRGoogleMap *mapView = (AIRGoogleMap *)view;
410
+ if (!mapView.indoorDisplay) {
411
+ return;
412
+ }
413
+ if ( levelIndex < [mapView.indoorDisplay.activeBuilding.levels count]) {
414
+ mapView.indoorDisplay.activeLevel = mapView.indoorDisplay.activeBuilding.levels[levelIndex];
415
+ }
416
+ }
417
+ }];
418
+ }
416
419
 
417
420
  + (BOOL)requiresMainQueueSetup {
418
- return YES;
421
+ return YES;
419
422
  }
420
423
 
421
424
  - (NSDictionary *)constantsToExport {
422
- return @{ @"legalNotice": [GMSServices openSourceLicenseInfo] };
425
+ return @{ @"legalNotice": [GMSServices openSourceLicenseInfo] };
423
426
  }
424
427
 
425
428
  - (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture {
426
- self.isGesture = gesture;
427
- AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
428
- [googleMapView willMove:gesture];
429
+ self.isGesture = gesture;
430
+ AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
431
+ [googleMapView willMove:gesture];
429
432
  }
430
433
 
431
434
  - (void)mapViewDidStartTileRendering:(GMSMapView *)mapView {
432
- AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
433
- [googleMapView didPrepareMap];
435
+ AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
436
+ [googleMapView didPrepareMap];
434
437
  }
435
438
 
436
439
  - (void)mapViewDidFinishTileRendering:(GMSMapView *)mapView {
437
- AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
438
- [googleMapView mapViewDidFinishTileRendering];
440
+ AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
441
+ [googleMapView mapViewDidFinishTileRendering];
439
442
  }
440
443
 
441
444
  - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
442
- AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
443
- return [googleMapView didTapMarker:marker];
445
+ AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
446
+ return [googleMapView didTapMarker:marker];
444
447
  }
445
448
 
446
449
  - (void)mapView:(GMSMapView *)mapView didTapOverlay:(GMSPolygon *)polygon {
447
- AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
448
- [googleMapView didTapPolygon:polygon];
450
+ AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
451
+ [googleMapView didTapPolygon:polygon];
449
452
  }
450
453
 
451
454
  - (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
452
- AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
453
- [googleMapView didTapAtCoordinate:coordinate];
455
+ AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
456
+ [googleMapView didTapAtCoordinate:coordinate];
454
457
  }
455
458
 
456
459
  - (void)mapView:(GMSMapView *)mapView didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate {
457
- AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
458
- [googleMapView didLongPressAtCoordinate:coordinate];
460
+ AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
461
+ [googleMapView didLongPressAtCoordinate:coordinate];
459
462
  }
460
463
 
461
464
  - (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position {
462
- AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
463
- [googleMapView didChangeCameraPosition:position isGesture:self.isGesture];
465
+ AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
466
+ [googleMapView didChangeCameraPosition:position isGesture:self.isGesture];
464
467
  }
465
468
 
466
469
  - (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position {
467
- AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
468
- [googleMapView idleAtCameraPosition:position isGesture:self.isGesture];
470
+ AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
471
+ [googleMapView idleAtCameraPosition:position isGesture:self.isGesture];
469
472
  }
470
473
 
471
474
  - (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker {
472
- AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
473
- return [aMarker.fakeMarker markerInfoWindow];}
475
+ AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
476
+ return [aMarker.fakeMarker markerInfoWindow];}
474
477
 
475
478
  - (UIView *)mapView:(GMSMapView *)mapView markerInfoContents:(GMSMarker *)marker {
476
- AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
477
- return [aMarker.fakeMarker markerInfoContents];
479
+ AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
480
+ return [aMarker.fakeMarker markerInfoContents];
478
481
  }
479
482
 
480
483
  - (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker {
481
- AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
482
- [aMarker.fakeMarker didTapInfoWindowOfMarker:aMarker];
484
+ AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
485
+ [aMarker.fakeMarker didTapInfoWindowOfMarker:aMarker];
483
486
  }
484
487
 
485
488
  - (void)mapView:(GMSMapView *)mapView didBeginDraggingMarker:(GMSMarker *)marker {
486
- AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
487
- [aMarker.fakeMarker didBeginDraggingMarker:aMarker];
489
+ AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
490
+ [aMarker.fakeMarker didBeginDraggingMarker:aMarker];
488
491
  }
489
492
 
490
493
  - (void)mapView:(GMSMapView *)mapView didEndDraggingMarker:(GMSMarker *)marker {
491
- AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
492
- [aMarker.fakeMarker didEndDraggingMarker:aMarker];
494
+ AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
495
+ [aMarker.fakeMarker didEndDraggingMarker:aMarker];
493
496
  }
494
497
 
495
498
  - (void)mapView:(GMSMapView *)mapView didDragMarker:(GMSMarker *)marker {
496
- AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
497
- [aMarker.fakeMarker didDragMarker:aMarker];
499
+ AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
500
+ [aMarker.fakeMarker didDragMarker:aMarker];
498
501
  }
499
502
 
500
503
  - (void)mapView:(GMSMapView *)mapView
501
- didTapPOIWithPlaceID:(NSString *)placeID
502
- name:(NSString *)name
503
- location:(CLLocationCoordinate2D)location {
504
+ didTapPOIWithPlaceID:(NSString *)placeID
505
+ name:(NSString *)name
506
+ location:(CLLocationCoordinate2D)location {
504
507
  AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
505
508
  [googleMapView didTapPOIWithPlaceID:placeID name:name location:location];
506
509
  }
@@ -508,23 +511,23 @@ RCT_EXPORT_METHOD(setIndoorActiveLevelIndex:(nonnull NSNumber *)reactTag
508
511
  #pragma mark Gesture Recognizer Handlers
509
512
 
510
513
  - (void)handleMapDrag:(UIPanGestureRecognizer*)recognizer {
511
- AIRGoogleMap *map = (AIRGoogleMap *)recognizer.view;
512
- if (!map.onPanDrag) return;
513
-
514
- CGPoint touchPoint = [recognizer locationInView:map];
515
- CLLocationCoordinate2D coord = [map.projection coordinateForPoint:touchPoint];
516
- map.onPanDrag(@{
517
- @"coordinate": @{
518
- @"latitude": @(coord.latitude),
519
- @"longitude": @(coord.longitude),
520
- },
521
- @"position": @{
522
- @"x": @(touchPoint.x),
523
- @"y": @(touchPoint.y),
524
- },
525
- @"numberOfTouches": @(recognizer.numberOfTouches),
526
- });
527
-
514
+ AIRGoogleMap *map = (AIRGoogleMap *)recognizer.view;
515
+ if (!map.onPanDrag) return;
516
+
517
+ CGPoint touchPoint = [recognizer locationInView:map];
518
+ CLLocationCoordinate2D coord = [map.projection coordinateForPoint:touchPoint];
519
+ map.onPanDrag(@{
520
+ @"coordinate": @{
521
+ @"latitude": @(coord.latitude),
522
+ @"longitude": @(coord.longitude),
523
+ },
524
+ @"position": @{
525
+ @"x": @(touchPoint.x),
526
+ @"y": @(touchPoint.y),
527
+ },
528
+ @"numberOfTouches": @(recognizer.numberOfTouches),
529
+ });
530
+
528
531
  }
529
532
 
530
533
  @end
@@ -196,9 +196,9 @@ using namespace facebook::react;
196
196
 
197
197
  _view.onIndoorLevelActivated = [self](NSDictionary* dictionary) {
198
198
  if (_eventEmitter) {
199
-
199
+
200
200
  auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
201
-
201
+
202
202
  facebook::react::RNMapsGoogleMapViewEventEmitter::OnIndoorLevelActivated data = {
203
203
  .activeLevelIndex= (int) [dictionary[@"activeLevelIndex"] integerValue],
204
204
  .name = [dictionary[@"name"] UTF8String],
@@ -214,7 +214,7 @@ using namespace facebook::react;
214
214
 
215
215
  NSError *jsError = nil;
216
216
  NSString *levelsStr = RCTJSONStringify(dictionary[@"levels"], &jsError);
217
-
217
+
218
218
  facebook::react::RNMapsGoogleMapViewEventEmitter::OnIndoorBuildingFocused data = {
219
219
  .underground = [dictionary[@"underground"] boolValue],
220
220
  .activeLevelIndex = (int) [dictionary[@"activeLevelIndex"] integerValue],
@@ -497,6 +497,12 @@ using namespace facebook::react;
497
497
  _legacyMapManager.googleMapId = mapID;
498
498
  }
499
499
  }
500
+ if (oldViewProps.customMapStyleString != newViewProps.customMapStyleString) {
501
+ NSString* customStyle = RCTNSStringFromString(newViewProps.customMapStyleString);
502
+ if (customStyle && [customStyle length]){
503
+ _legacyMapManager.customMapStyle = customStyle;
504
+ }
505
+ }
500
506
  if (!newViewProps.zoomTapEnabled) {
501
507
  _legacyMapManager.zoomTapEnabled = newViewProps.zoomTapEnabled;
502
508
  } else {
@@ -573,6 +579,8 @@ using namespace facebook::react;
573
579
  REMAP_MAPVIEW_PROP(scrollEnabled)
574
580
 
575
581
  REMAP_MAPVIEW_STRING_PROP(kmlSrc)
582
+ REMAP_MAPVIEW_STRING_PROP(customMapStyleString)
583
+
576
584
 
577
585
  if (newViewProps.minZoom != oldViewProps.minZoom || newViewProps.maxZoom != oldViewProps.maxZoom){
578
586
  [_view setMinZoom:newViewProps.minZoom maxZoom:newViewProps.maxZoom];
@@ -30,7 +30,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
30
30
  BOOL _calloutIsOpen;
31
31
  NSInteger _zIndexBeforeOpen;
32
32
  BOOL _useLegacyPinView;
33
-
33
+
34
34
  CADisplayLink *_displayLink;
35
35
  CLLocationCoordinate2D _startCoordinate;
36
36
  CLLocationCoordinate2D _endCoordinate;
@@ -52,13 +52,13 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
52
52
  // Make sure we use the image size when available
53
53
  CGSize size = self.image ? self.image.size : frame.size;
54
54
  CGRect bounds = {CGPointZero, size};
55
-
55
+
56
56
  // The MapView is basically in charge of figuring out the center position of the marker view. If the view changed in
57
57
  // height though, we need to compensate in such a way that the bottom of the marker stays at the same spot on the
58
58
  // map.
59
59
  CGFloat dy = (bounds.size.height - self.bounds.size.height) / 2;
60
60
  CGPoint center = (CGPoint){ self.center.x, self.center.y - dy };
61
-
61
+
62
62
  // Avoid crashes due to nan coords
63
63
  if (isnan(center.x) || isnan(center.y) ||
64
64
  isnan(bounds.origin.x) || isnan(bounds.origin.y) ||
@@ -67,7 +67,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
67
67
  self.reactTag, self, NSStringFromCGPoint(center), NSStringFromCGRect(bounds));
68
68
  return;
69
69
  }
70
-
70
+
71
71
  self.center = center;
72
72
  self.bounds = bounds;
73
73
  }
@@ -102,31 +102,31 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
102
102
  {
103
103
  if ([self shouldUsePinView]) {
104
104
  // In this case, we want to render a platform "default" legacy marker.
105
-
106
-
105
+
106
+
107
107
  if (_pinView == nil && _useLegacyPinView) {
108
108
  _pinView = [[MKPinAnnotationView alloc] initWithAnnotation:self reuseIdentifier: nil];
109
109
  [self addGestureRecognizerToView:_pinView];
110
110
  _pinView.annotation = self;
111
-
111
+
112
112
  if ([_pinView respondsToSelector:@selector(setPinTintColor:)]) {
113
113
  _pinView.pinTintColor = self.pinColor;
114
114
  }
115
-
115
+
116
116
  _pinView.draggable = self.draggable;
117
117
  _pinView.layer.zPosition = self.zIndex;
118
118
  _pinView.displayPriority = self.displayPriority;
119
119
  _pinView.zPriority = self.zIndex;
120
120
  return _pinView;
121
121
  }
122
-
123
-
124
-
122
+
123
+
124
+
125
125
  if (_markerView == nil && !_useLegacyPinView) {
126
126
  _markerView = [[MKMarkerAnnotationView alloc] initWithAnnotation:self reuseIdentifier: nil];
127
127
  [self addGestureRecognizerToView:_markerView];
128
128
  _markerView.annotation = self;
129
-
129
+
130
130
  _markerView.draggable = self.draggable;
131
131
  _markerView.layer.zPosition = self.zIndex;
132
132
  _markerView.markerTintColor = self.pinColor;
@@ -135,7 +135,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
135
135
  _markerView.displayPriority = self.displayPriority;
136
136
  _markerView.zPriority = self.zIndex;
137
137
 
138
-
138
+
139
139
  }
140
140
  return _markerView ?: _pinView;
141
141
  } else {
@@ -152,14 +152,14 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
152
152
  - (void)fillCalloutView:(SMCalloutView *)calloutView
153
153
  {
154
154
  // Set everything necessary on the calloutView before it becomes visible.
155
-
155
+
156
156
  // Apply the MKAnnotationView's desired calloutOffset (from the top-middle of the view)
157
157
  if ([self shouldUsePinView] && !_hasSetCalloutOffset && _useLegacyPinView) {
158
158
  calloutView.calloutOffset = CGPointMake(-8,0);
159
159
  } else {
160
160
  calloutView.calloutOffset = self.calloutOffset;
161
161
  }
162
-
162
+
163
163
  if (self.calloutView) {
164
164
  calloutView.title = nil;
165
165
  calloutView.subtitle = nil;
@@ -172,13 +172,13 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
172
172
  // as a result, we use the default "masked" background view.
173
173
  calloutView.backgroundView = [SMCalloutMaskedBackgroundView new];
174
174
  }
175
-
175
+
176
176
  // when this is set, the callout's content will be whatever react views the user has put as the callout's
177
177
  // children.
178
178
  calloutView.contentView = self.calloutView;
179
-
179
+
180
180
  } else {
181
-
181
+
182
182
  // if there is no calloutView, it means the user wants to use the default callout behavior with title/subtitle
183
183
  // pairs.
184
184
  calloutView.title = self.title;
@@ -192,12 +192,12 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
192
192
  {
193
193
  _calloutIsOpen = YES;
194
194
  [self setZIndex:_zIndexBeforeOpen];
195
-
195
+
196
196
  MKAnnotationView *annotationView = [self getAnnotationView];
197
-
197
+
198
198
  [self setSelected:YES animated:NO];
199
199
  [self.map selectAnnotation:self animated:NO];
200
-
200
+
201
201
  id event = @{
202
202
  @"action": @"marker-select",
203
203
  @"id": self.identifier ?: @"unknown",
@@ -206,17 +206,17 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
206
206
  @"longitude": @(self.coordinate.longitude)
207
207
  }
208
208
  };
209
-
209
+
210
210
  if (self.map.onMarkerSelect) self.map.onMarkerSelect(event);
211
211
  if (self.onSelect) self.onSelect(event);
212
-
212
+
213
213
  if (![self shouldShowCalloutView]) {
214
214
  // no callout to show
215
215
  return;
216
216
  }
217
-
217
+
218
218
  [self fillCalloutView:self.map.calloutView];
219
-
219
+
220
220
  // This is where we present our custom callout view... MapKit's built-in callout doesn't have the flexibility
221
221
  // we need, but a lot of work was done by Nick Farina to make this identical to MapKit's built-in.
222
222
  [self.map.calloutView presentCalloutFromRect:annotationView.bounds
@@ -244,12 +244,12 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
244
244
  - (void)_handleTap:(UITapGestureRecognizer *)recognizer {
245
245
  AIRMapMarker *marker = self;
246
246
  if (!marker) return;
247
-
247
+
248
248
  if (marker.selected) {
249
249
  CGPoint touchPoint = [recognizer locationInView:marker.map.calloutView];
250
250
  CGRect bubbleFrame = [self.calloutView convertRect:marker.map.calloutView.bounds toView:marker.map];
251
251
  CGPoint touchPointReal = [recognizer locationInView:self.calloutView];
252
-
252
+
253
253
  UIView *calloutView = [marker.map.calloutView hitTest:touchPoint withEvent:nil];
254
254
  if (calloutView) {
255
255
  // the callout (or its subview) got clicked, not the marker
@@ -263,7 +263,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
263
263
  }
264
264
  tmp = tmp.superview;
265
265
  }
266
-
266
+
267
267
  id event = @{
268
268
  @"action": calloutSubview ? @"callout-inside-press" : @"callout-press",
269
269
  @"id": marker.identifier ?: @"unknown",
@@ -278,7 +278,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
278
278
  @"height": @(bubbleFrame.size.height),
279
279
  }
280
280
  };
281
-
281
+
282
282
  if (calloutSubview) calloutSubview.onPress(event);
283
283
  if (marker.onCalloutPress) marker.onCalloutPress(event);
284
284
  if (marker.calloutView && marker.calloutView.onPress) marker.calloutView.onPress(event);
@@ -286,7 +286,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
286
286
  return;
287
287
  }
288
288
  }
289
-
289
+
290
290
  // the actual marker got clicked
291
291
  CGPoint touchPointReal = [recognizer locationInView:self.calloutView];
292
292
  id event = @{
@@ -301,10 +301,10 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
301
301
  @"y": @(touchPointReal.y),
302
302
  }
303
303
  };
304
-
304
+
305
305
  if (marker.onPress) marker.onPress(event);
306
306
  if (marker.map.onMarkerPress) marker.map.onMarkerPress(event);
307
-
307
+
308
308
  [marker.map selectAnnotation:marker animated:NO];
309
309
  }
310
310
 
@@ -314,10 +314,10 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
314
314
  [self setZIndex:_zIndexBeforeOpen];
315
315
  // hide the callout view
316
316
  [self.map.calloutView dismissCalloutAnimated:YES];
317
-
317
+
318
318
  [self setSelected:NO animated:NO];
319
319
  [self.map deselectAnnotation:self animated:NO];
320
-
320
+
321
321
  id event = @{
322
322
  @"action": @"marker-deselect",
323
323
  @"id": self.identifier ?: @"unknown",
@@ -326,7 +326,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
326
326
  @"longitude": @(self.coordinate.longitude)
327
327
  }
328
328
  };
329
-
329
+
330
330
  if (self.map.onMarkerDeselect) self.map.onMarkerDeselect(event);
331
331
  if (self.onDeselect) self.onDeselect(event);
332
332
  }
@@ -355,13 +355,13 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
355
355
  - (void)setImageSrc:(NSString *)imageSrc
356
356
  {
357
357
  _imageSrc = imageSrc;
358
-
358
+
359
359
  if (_reloadImageCancellationBlock) {
360
360
  _reloadImageCancellationBlock();
361
361
  _reloadImageCancellationBlock = nil;
362
362
  }
363
363
  __weak __typeof(self) weakSelf = self;
364
-
364
+
365
365
  _reloadImageCancellationBlock = [[[RCTBridge currentBridge] moduleForName:@"ImageLoader"] loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc]
366
366
  size:self.bounds.size
367
367
  scale:RCTScreenScale()
@@ -384,7 +384,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
384
384
  - (void)setPinColor:(UIColor *)pinColor
385
385
  {
386
386
  _pinColor = pinColor;
387
-
387
+
388
388
  if(_useLegacyPinView && [_pinView respondsToSelector:@selector(setPinTintColor:)]) {
389
389
  _pinView.pinTintColor = _pinColor;
390
390
  } else {
@@ -412,6 +412,19 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
412
412
  self.layer.zPosition = _zIndex;
413
413
  }
414
414
  }
415
+ - (void)layoutSubviews
416
+ {
417
+ [super layoutSubviews];
418
+
419
+ CGRect reactFrame = self.frame;
420
+
421
+ UIView *firstSubView = self.subviews.firstObject;
422
+ if (firstSubView && (CGRectGetWidth(firstSubView.frame) > CGRectGetWidth(reactFrame) ||
423
+ CGRectGetHeight(firstSubView.frame) > CGRectGetHeight(reactFrame))) {
424
+ reactFrame = firstSubView.frame;
425
+ }
426
+ [self reactSetFrame:reactFrame];
427
+ }
415
428
 
416
429
  - (void)setUseLegacyPinView:(BOOL)value {
417
430
  _useLegacyPinView = value;
@@ -422,16 +435,16 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
422
435
  NSLog(@"Animation already in progress. Rejecting new animation request.");
423
436
  return;
424
437
  }
425
-
438
+
426
439
  // Mark as animating
427
440
  _isAnimating = YES;
428
-
441
+
429
442
  // Store animation parameters
430
443
  _startCoordinate = self.coordinate;
431
444
  _endCoordinate = newCoordinate;
432
445
  _animationDuration = duration;
433
446
  _animationStartTime = [NSDate timeIntervalSinceReferenceDate];
434
-
447
+
435
448
  // Start a CADisplayLink
436
449
  if (_displayLink) {
437
450
  [_displayLink invalidate];
@@ -443,15 +456,15 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
443
456
  - (void)updatePosition {
444
457
  NSTimeInterval elapsed = [NSDate timeIntervalSinceReferenceDate] - _animationStartTime;
445
458
  CGFloat progress = MIN(elapsed / _animationDuration, 1.0);
446
-
459
+
447
460
  // Interpolate coordinates
448
461
  CLLocationDegrees currentLatitude = _startCoordinate.latitude + progress * (_endCoordinate.latitude - _startCoordinate.latitude);
449
462
  CLLocationDegrees currentLongitude = _startCoordinate.longitude + progress * (_endCoordinate.longitude - _startCoordinate.longitude);
450
-
463
+
451
464
  // Update annotation's coordinate
452
465
  CLLocationCoordinate2D currentCoordinate = CLLocationCoordinate2DMake(currentLatitude, currentLongitude);
453
466
  [self setValue:[NSValue valueWithMKCoordinate:currentCoordinate] forKey:@"coordinate"];
454
-
467
+
455
468
  // Stop the animation when complete
456
469
  if (progress == 1.0) {
457
470
  [_displayLink invalidate];
@@ -66,6 +66,7 @@ RNMapsGoogleMapViewProps::RNMapsGoogleMapViewProps(
66
66
  showsTraffic(convertRawProp(context, rawProps, "showsTraffic", sourceProps.showsTraffic, {false})),
67
67
  showsUserLocation(convertRawProp(context, rawProps, "showsUserLocation", sourceProps.showsUserLocation, {false})),
68
68
  userInterfaceStyle(convertRawProp(context, rawProps, "userInterfaceStyle", sourceProps.userInterfaceStyle, {RNMapsGoogleMapViewUserInterfaceStyle::System})),
69
+ customMapStyleString(convertRawProp(context, rawProps, "customMapStyleString", sourceProps.customMapStyleString, {})),
69
70
  userLocationCalloutEnabled(convertRawProp(context, rawProps, "userLocationCalloutEnabled", sourceProps.userLocationCalloutEnabled, {false})),
70
71
  userLocationFastestInterval(convertRawProp(context, rawProps, "userLocationFastestInterval", sourceProps.userLocationFastestInterval, {0})),
71
72
  userLocationPriority(convertRawProp(context, rawProps, "userLocationPriority", sourceProps.userLocationPriority, {RNMapsGoogleMapViewUserLocationPriority::High})),
@@ -391,6 +391,7 @@ class RNMapsGoogleMapViewProps final : public ViewProps {
391
391
  bool showsTraffic{false};
392
392
  bool showsUserLocation{false};
393
393
  RNMapsGoogleMapViewUserInterfaceStyle userInterfaceStyle{RNMapsGoogleMapViewUserInterfaceStyle::System};
394
+ std::string customMapStyleString{};
394
395
  bool userLocationCalloutEnabled{false};
395
396
  int userLocationFastestInterval{0};
396
397
  RNMapsGoogleMapViewUserLocationPriority userLocationPriority{RNMapsGoogleMapViewUserLocationPriority::High};
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "main": "src/index.ts",
6
6
  "author": "Leland Richardson <leland.m.richardson@gmail.com>",
7
7
  "homepage": "https://github.com/react-native-maps/react-native-maps#readme",
8
- "version": "1.21.0-alpha.133",
8
+ "version": "1.21.0-alpha.135",
9
9
  "license": "MIT",
10
10
  "scripts": {
11
11
  "lint": "eslint . --max-warnings 0",
package/src/MapView.tsx CHANGED
@@ -1134,11 +1134,16 @@ class MapView extends React.Component<MapViewProps, State> {
1134
1134
  region,
1135
1135
  provider,
1136
1136
  children,
1137
+ customMapStyle,
1137
1138
  ...restProps
1138
1139
  } = this.props;
1139
1140
 
1140
1141
  /* eslint-enable @typescript-eslint/no-unused-vars */
1141
1142
  const userInterfaceStyle = this.props.userInterfaceStyle || 'system';
1143
+ const customMapStyleString = customMapStyle
1144
+ ? JSON.stringify(this.props.customMapStyle)
1145
+ : undefined;
1146
+
1142
1147
  const props: MapFabricNativeProps = {
1143
1148
  onMapReady: this._onMapReady,
1144
1149
  liteMode: this.props.liteMode,
@@ -1150,6 +1155,7 @@ class MapView extends React.Component<MapViewProps, State> {
1150
1155
  onMarkerDeselect: this.handleMarkerDeselect,
1151
1156
  onKmlReady: this.handleKmlReady,
1152
1157
  userInterfaceStyle: userInterfaceStyle,
1158
+ customMapStyleString,
1153
1159
  minZoom: minZoomLevel,
1154
1160
  maxZoom: maxZoomLevel,
1155
1161
  onRegionChange: this.handleRegionChange,
@@ -774,6 +774,15 @@ export interface MapFabricNativeProps extends ViewProps {
774
774
  */
775
775
  userInterfaceStyle?: WithDefault<'system' | 'light' | 'dark', 'system'>;
776
776
 
777
+ /**
778
+ * Adds custom styling to the map component.
779
+ * See [README](https://github.com/react-native-maps/react-native-maps#customizing-the-map-style) for more information.
780
+ *
781
+ * @platform iOS: Google Maps only
782
+ * @platform Android: Supported
783
+ */
784
+ customMapStyleString?: string;
785
+
777
786
  /**
778
787
  * If `true` clicking user location will show the default callout for userLocation annotation.
779
788
  *
@@ -923,6 +923,15 @@ export interface MapFabricNativeProps extends ViewProps {
923
923
  */
924
924
  userInterfaceStyle?: WithDefault<'system' | 'light' | 'dark', 'system'>;
925
925
 
926
+ /**
927
+ * Adds custom styling to the map component.
928
+ * See [README](https://github.com/react-native-maps/react-native-maps#customizing-the-map-style) for more information.
929
+ *
930
+ * @platform iOS: Google Maps only
931
+ * @platform Android: Supported
932
+ */
933
+ customMapStyleString?: string;
934
+
926
935
  /**
927
936
  * The title of the annotation for current user location.
928
937
  *