react-native-maps 1.21.0-alpha.11 → 1.21.0-alpha.12

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.
@@ -12,7 +12,7 @@
12
12
 
13
13
  @class AIRGoogleMapMarker;
14
14
 
15
- @interface AIRGMSMarker : GMSAdvancedMarker
15
+ @interface AIRGMSMarker : GMSMarker
16
16
  @property (nonatomic, strong) NSString *identifier;
17
17
  @property (nonatomic, weak) AIRGoogleMapMarker *fakeMarker;
18
18
  @property (nonatomic, copy) RCTBubblingEventBlock onPress;
@@ -239,7 +239,7 @@ id regionAsJSON(MKCoordinateRegion region) {
239
239
  // This is where we intercept them and do the appropriate underlying mapview action.
240
240
  if ([subview isKindOfClass:[AIRGoogleMapMarker class]]) {
241
241
  AIRGoogleMapMarker *marker = (AIRGoogleMapMarker*)subview;
242
- marker.realMarker.map = self;
242
+ [marker didInsertInMap:self];
243
243
  [self.markers addObject:marker];
244
244
  } else if ([subview isKindOfClass:[AIRGoogleMapPolygon class]]) {
245
245
  AIRGoogleMapPolygon *polygon = (AIRGoogleMapPolygon*)subview;
@@ -784,7 +784,7 @@ id regionAsJSON(MKCoordinateRegion region) {
784
784
  NSString *result = [config objectForKey:@"result"];
785
785
  NSString *filePath = [config objectForKey:@"filePath"];
786
786
 
787
-
787
+
788
788
  // TODO: currently we are ignoring width, height, region
789
789
 
790
790
  UIGraphicsBeginImageContextWithOptions(self.frame.size, YES, 0.0f);
@@ -798,14 +798,14 @@ id regionAsJSON(MKCoordinateRegion region) {
798
798
  } else if([format isEqualToString:@"jpg"]) {
799
799
  data = UIImageJPEGRepresentation(image, quality.floatValue);
800
800
  }
801
-
801
+
802
802
  if ([result isEqualToString:@"file"]) {
803
803
  [data writeToFile:filePath atomically:YES];
804
804
  callback(filePath);
805
805
  } else if ([result isEqualToString:@"base64"]) {
806
806
  callback([data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]);
807
807
  }
808
-
808
+
809
809
  UIGraphicsEndImageContext();
810
810
  }
811
811
 
@@ -53,6 +53,8 @@
53
53
  - (void)didDragMarker:(AIRGMSMarker *)marker;
54
54
  - (id)makeEventData;
55
55
  - (id)makeEventData:(NSString *)action;
56
+ - (UIView *) iconView;
57
+ - (void) didInsertInMap:(AIRGoogleMap *) map;
56
58
  @end
57
59
 
58
60
  #endif
@@ -16,141 +16,225 @@
16
16
  #import "AIRDummyView.h"
17
17
 
18
18
  CGRect unionRect(CGRect a, CGRect b) {
19
- return CGRectMake(
20
- MIN(a.origin.x, b.origin.x),
21
- MIN(a.origin.y, b.origin.y),
22
- MAX(a.size.width, b.size.width),
23
- MAX(a.size.height, b.size.height));
19
+ return CGRectMake(
20
+ MIN(a.origin.x, b.origin.x),
21
+ MIN(a.origin.y, b.origin.y),
22
+ MAX(a.size.width, b.size.width),
23
+ MAX(a.size.height, b.size.height));
24
24
  }
25
25
 
26
26
  @interface AIRGoogleMapMarker ()
27
27
  @end
28
28
 
29
29
  @implementation AIRGoogleMapMarker {
30
- RCTImageLoaderCancellationBlock _reloadImageCancellationBlock;
31
- __weak UIImageView *_iconImageView;
32
- UIView *_iconView;
30
+ RCTImageLoaderCancellationBlock _reloadImageCancellationBlock;
31
+ RCTBubblingEventBlock _onPress;
32
+ RCTBubblingEventBlock _onSelect;
33
+ RCTBubblingEventBlock _onDeselect;
34
+ __weak UIImageView *_iconImageView;
35
+ UIView *_iconView;
36
+ UIColor *_pinColor;
37
+ CLLocationCoordinate2D _coordinates;
38
+ CLLocationDegrees _rotation;
39
+ BOOL _tracksInfoWindowChanges;
40
+ BOOL _tracksViewChanges;
41
+ BOOL _draggable;
42
+ BOOL _tappable;
43
+ BOOL _flat;
44
+ double _opacity;
45
+ NSString* _identifier;
46
+ NSString* _title;
47
+ NSString* _subtitle;
48
+
33
49
  }
34
50
 
35
51
  - (instancetype)init
36
52
  {
37
- if ((self = [super init])) {
38
- _realMarker = [[AIRGMSMarker alloc] init];
39
- _realMarker.fakeMarker = self;
40
- _realMarker.tracksViewChanges = true;
41
- _realMarker.tracksInfoWindowChanges = false;
42
- }
43
- return self;
53
+ if ((self = [super init])) {
54
+ _tracksViewChanges = true;
55
+ _tracksInfoWindowChanges = false;
56
+ _tappable = true;
57
+ _opacity = 1.0;
58
+ }
59
+ return self;
44
60
  }
45
61
 
46
62
  - (void)layoutSubviews {
47
- float width = 0;
48
- float height = 0;
63
+ float width = 0;
64
+ float height = 0;
65
+
66
+ for (UIView *v in [_iconView subviews]) {
49
67
 
50
- for (UIView *v in [_iconView subviews]) {
68
+ float fw = v.frame.origin.x + v.frame.size.width;
69
+ float fh = v.frame.origin.y + v.frame.size.height;
51
70
 
52
- float fw = v.frame.origin.x + v.frame.size.width;
53
- float fh = v.frame.origin.y + v.frame.size.height;
71
+ width = MAX(fw, width);
72
+ height = MAX(fh, height);
73
+ }
74
+
75
+ [_iconView setFrame:CGRectMake(0, 0, width, height)];
76
+ }
54
77
 
55
- width = MAX(fw, width);
56
- height = MAX(fh, height);
57
- }
58
78
 
59
- [_iconView setFrame:CGRectMake(0, 0, width, height)];
79
+ - (UIView *) iconView
80
+ {
81
+ return _iconView;
60
82
  }
61
83
 
84
+ - (void) didUpdateReactSubviews
85
+ {
86
+ [super didUpdateReactSubviews];
87
+ if (_iconView){
88
+ [_iconView setFrame:self.frame];
89
+ }
90
+ }
62
91
 
92
+ - (void) didInsertInMap:(AIRGoogleMap *) map
93
+ {
94
+ _realMarker = [AIRGMSMarker new];
95
+ _realMarker.fakeMarker = self;
96
+ _realMarker.tracksViewChanges = _tracksViewChanges;
97
+ _realMarker.tracksInfoWindowChanges = _tracksInfoWindowChanges;
98
+
99
+ [_realMarker setPosition:_coordinates];
100
+ if (_iconView){
101
+ [_realMarker setIconView:_iconView];
102
+ }
103
+ if (_rotation != 0){
104
+ [_realMarker setRotation:_rotation];
105
+ }
106
+ if (_identifier){
107
+ [_realMarker setIdentifier:_identifier];
108
+ }
109
+ if (_title){
110
+ [_realMarker setTitle:_title];
111
+ }
112
+ if (_subtitle){
113
+ [_realMarker setSnippet:_subtitle];
114
+ }
115
+ if (!CGPointEqualToPoint(_anchor, CGPointZero)){
116
+ [_realMarker setGroundAnchor:_anchor];
117
+ }
118
+ if (!CGPointEqualToPoint(_calloutAnchor, CGPointZero)){
119
+ [_realMarker setInfoWindowAnchor:_calloutAnchor];
120
+ }
121
+ if (_flat){
122
+ [_realMarker setFlat:_flat];
123
+ }
124
+ if (_draggable){
125
+ [_realMarker setDraggable:_draggable];
126
+ }
127
+ [_realMarker setTappable:_tappable];
128
+ if (_pinColor){
129
+ _realMarker.icon = [GMSMarker markerImageWithColor:_pinColor];
130
+ }
131
+ if (_opacity != 1.0){
132
+ [_realMarker setOpacity:_opacity];
133
+ }
134
+ if (_onSelect){
135
+ [_realMarker setOnSelect:_onSelect];
136
+ }
137
+ if (_onDeselect){
138
+ [_realMarker setOnDeselect:_onDeselect];
139
+ }
140
+ if (_onPress){
141
+ [_realMarker setOnPress:_onPress];
142
+ }
143
+ [_realMarker setMap:map];
144
+ }
63
145
 
64
146
  - (void)iconViewInsertSubview:(UIView*)subview atIndex:(NSInteger)atIndex {
65
- if (!_realMarker.iconView) {
66
- _iconView = [[UIView alloc] init];
67
- _realMarker.iconView = _iconView;
68
- }
69
- [_iconView insertSubview:subview atIndex:atIndex];
147
+ if (!_iconView){
148
+ _iconView = [[UIView alloc] init];
149
+ }
150
+ if (!_realMarker.iconView) {
151
+ _realMarker.iconView = _iconView;
152
+ }
153
+ [_iconView insertSubview:subview atIndex:atIndex];
70
154
  }
71
155
 
72
156
  - (void)insertReactSubview:(id<RCTComponent>)subview atIndex:(NSInteger)atIndex {
73
- if ([subview isKindOfClass:[AIRGoogleMapCallout class]]) {
74
- self.calloutView = (AIRGoogleMapCallout *)subview;
75
- } else { // a child view of the marker
76
- [self iconViewInsertSubview:(UIView*)subview atIndex:atIndex+1];
77
- }
78
- AIRDummyView *dummySubview = [[AIRDummyView alloc] initWithView:(UIView *)subview];
79
- [super insertReactSubview:(UIView*)dummySubview atIndex:atIndex];
157
+ if ([subview isKindOfClass:[AIRGoogleMapCallout class]]) {
158
+ self.calloutView = (AIRGoogleMapCallout *)subview;
159
+ } else { // a child view of the marker
160
+ [self iconViewInsertSubview:(UIView*)subview atIndex:atIndex+1];
161
+ }
162
+ AIRDummyView *dummySubview = [[AIRDummyView alloc] initWithView:(UIView *)subview];
163
+ [super insertReactSubview:(UIView*)dummySubview atIndex:atIndex];
80
164
  }
81
165
 
82
166
  - (void)removeReactSubview:(id<RCTComponent>)dummySubview {
83
- UIView *subview = [dummySubview isKindOfClass:[AIRDummyView class]] ? ((AIRDummyView *)dummySubview).view : (UIView *)dummySubview;
167
+ UIView *subview = [dummySubview isKindOfClass:[AIRDummyView class]] ? ((AIRDummyView *)dummySubview).view : (UIView *)dummySubview;
84
168
 
85
- if ([subview isKindOfClass:[AIRGoogleMapCallout class]]) {
86
- self.calloutView = nil;
87
- } else {
88
- [subview removeFromSuperview];
89
- }
90
- [super removeReactSubview:(UIView*)dummySubview];
169
+ if ([subview isKindOfClass:[AIRGoogleMapCallout class]]) {
170
+ self.calloutView = nil;
171
+ } else {
172
+ [subview removeFromSuperview];
173
+ }
174
+ [super removeReactSubview:(UIView*)dummySubview];
91
175
  }
92
176
 
93
177
  - (void)showCalloutView {
94
- [_realMarker.map setSelectedMarker:_realMarker];
178
+ [_realMarker.map setSelectedMarker:_realMarker];
95
179
  }
96
180
 
97
181
  - (void)hideCalloutView {
98
- [_realMarker.map setSelectedMarker:Nil];
182
+ [_realMarker.map setSelectedMarker:Nil];
99
183
  }
100
184
 
101
185
  - (void)redraw {
102
- if (!_realMarker.iconView) return;
186
+ if (!_realMarker.iconView) return;
103
187
 
104
- BOOL oldValue = _realMarker.tracksViewChanges;
188
+ BOOL oldValue = _realMarker.tracksViewChanges;
105
189
 
106
- if (oldValue == YES)
107
- {
108
- // Immediate refresh, like right now. Not waiting for next frame.
109
- UIView *view = _realMarker.iconView;
110
- _realMarker.iconView = nil;
111
- _realMarker.iconView = view;
112
- }
113
- else
114
- {
115
- // Refresh according to docs
116
- _realMarker.tracksViewChanges = YES;
117
- _realMarker.tracksViewChanges = NO;
118
- }
190
+ if (oldValue == YES)
191
+ {
192
+ // Immediate refresh, like right now. Not waiting for next frame.
193
+ UIView *view = _realMarker.iconView;
194
+ _realMarker.iconView = nil;
195
+ _realMarker.iconView = view;
196
+ }
197
+ else
198
+ {
199
+ // Refresh according to docs
200
+ _realMarker.tracksViewChanges = YES;
201
+ _realMarker.tracksViewChanges = NO;
202
+ }
119
203
  }
120
204
 
121
205
  - (UIView *)markerInfoContents {
122
- if (self.calloutView && !self.calloutView.tooltip) {
123
- return self.calloutView;
124
- }
125
- return nil;
206
+ if (self.calloutView && !self.calloutView.tooltip) {
207
+ return self.calloutView;
208
+ }
209
+ return nil;
126
210
  }
127
211
 
128
212
  - (UIView *)markerInfoWindow {
129
- if (self.calloutView && self.calloutView.tooltip) {
130
- return self.calloutView;
131
- }
132
- return nil;
213
+ if (self.calloutView && self.calloutView.tooltip) {
214
+ return self.calloutView;
215
+ }
216
+ return nil;
133
217
  }
134
218
 
135
219
  - (void)didTapInfoWindowOfMarker:(AIRGMSMarker *)marker point:(CGPoint)point frame:(CGRect)frame {
136
- if (self.calloutView && self.calloutView.onPress) {
137
- //todo: why not 'callout-press' ?
138
- id event = @{
139
- @"action": @"marker-overlay-press",
140
- @"id": self.identifier ?: @"unknown",
141
- @"point": @{
142
- @"x": @(point.x),
143
- @"y": @(point.y),
144
- },
145
- @"frame": @{
146
- @"x": @(frame.origin.x),
147
- @"y": @(frame.origin.y),
148
- @"width": @(frame.size.width),
149
- @"height": @(frame.size.height),
150
- }
151
- };
152
- self.calloutView.onPress(event);
153
- }
220
+ if (self.calloutView && self.calloutView.onPress) {
221
+ //todo: why not 'callout-press' ?
222
+ id event = @{
223
+ @"action": @"marker-overlay-press",
224
+ @"id": self.identifier ?: @"unknown",
225
+ @"point": @{
226
+ @"x": @(point.x),
227
+ @"y": @(point.y),
228
+ },
229
+ @"frame": @{
230
+ @"x": @(frame.origin.x),
231
+ @"y": @(frame.origin.y),
232
+ @"width": @(frame.size.width),
233
+ @"height": @(frame.size.height),
234
+ }
235
+ };
236
+ self.calloutView.onPress(event);
237
+ }
154
238
  }
155
239
 
156
240
  - (void)didTapInfoWindowOfMarker:(AIRGMSMarker *)marker {
@@ -161,19 +245,19 @@ CGRect unionRect(CGRect a, CGRect b) {
161
245
  if (subview && subview.onPress) {
162
246
  //todo: why not 'callout-inside-press' ?
163
247
  id event = @{
164
- @"action": @"marker-inside-overlay-press",
165
- @"id": self.identifier ?: @"unknown",
166
- @"point": @{
167
- @"x": @(point.x),
168
- @"y": @(point.y),
169
- },
170
- @"frame": @{
171
- @"x": @(frame.origin.x),
172
- @"y": @(frame.origin.y),
173
- @"width": @(frame.size.width),
174
- @"height": @(frame.size.height),
175
- }
176
- };
248
+ @"action": @"marker-inside-overlay-press",
249
+ @"id": self.identifier ?: @"unknown",
250
+ @"point": @{
251
+ @"x": @(point.x),
252
+ @"y": @(point.y),
253
+ },
254
+ @"frame": @{
255
+ @"x": @(frame.origin.x),
256
+ @"y": @(frame.origin.y),
257
+ @"width": @(frame.size.width),
258
+ @"height": @(frame.size.height),
259
+ }
260
+ };
177
261
  subview.onPress(event);
178
262
  } else {
179
263
  [self didTapInfoWindowOfMarker:marker point:point frame:frame];
@@ -181,30 +265,32 @@ CGRect unionRect(CGRect a, CGRect b) {
181
265
  }
182
266
 
183
267
  - (void)didBeginDraggingMarker:(AIRGMSMarker *)marker {
184
- if (!self.onDragStart) return;
185
- self.onDragStart([self makeEventData]);
268
+ if (!self.onDragStart) return;
269
+ self.onDragStart([self makeEventData]);
186
270
  }
187
271
 
188
272
  - (void)didEndDraggingMarker:(AIRGMSMarker *)marker {
189
- if (!self.onDragEnd) return;
190
- self.onDragEnd([self makeEventData]);
273
+ if (!self.onDragEnd) return;
274
+ self.onDragEnd([self makeEventData]);
191
275
  }
192
276
 
193
277
  - (void)didDragMarker:(AIRGMSMarker *)marker {
194
- if (!self.onDrag) return;
195
- self.onDrag([self makeEventData]);
278
+ if (!self.onDrag) return;
279
+ self.onDrag([self makeEventData]);
196
280
  }
197
281
 
198
282
  - (void)setCoordinate:(CLLocationCoordinate2D)coordinate {
199
- _realMarker.position = coordinate;
283
+ _realMarker.position = coordinate;
284
+ _coordinates = coordinate;
200
285
  }
201
286
 
202
287
  - (CLLocationCoordinate2D)coordinate {
203
- return _realMarker.position;
288
+ return _realMarker.position;
204
289
  }
205
290
 
206
291
  - (void)setRotation:(CLLocationDegrees)rotation {
207
292
  _realMarker.rotation = rotation;
293
+ _rotation = rotation;
208
294
  }
209
295
 
210
296
  - (CLLocationDegrees)rotation {
@@ -212,220 +298,230 @@ CGRect unionRect(CGRect a, CGRect b) {
212
298
  }
213
299
 
214
300
  - (void)setIdentifier:(NSString *)identifier {
215
- _realMarker.identifier = identifier;
301
+ _realMarker.identifier = identifier;
302
+ _identifier = identifier;
216
303
  }
217
304
 
218
305
  - (NSString *)identifier {
219
- return _realMarker.identifier;
306
+ return _realMarker.identifier;
220
307
  }
221
308
 
222
309
  - (void)setOnPress:(RCTBubblingEventBlock)onPress {
223
- _realMarker.onPress = onPress;
310
+ _realMarker.onPress = onPress;
311
+ _onPress = onPress;
224
312
  }
225
313
 
226
314
  - (RCTBubblingEventBlock)onPress {
227
- return _realMarker.onPress;
315
+ return _realMarker.onPress;
228
316
  }
229
317
 
230
318
  - (void)setOnSelect:(RCTDirectEventBlock)onSelect {
231
- _realMarker.onSelect = onSelect;
319
+ _realMarker.onSelect = onSelect;
320
+ _onSelect = onSelect;
232
321
  }
233
322
 
234
323
  - (RCTDirectEventBlock)onSelect {
235
- return _realMarker.onSelect;
324
+ return _realMarker.onSelect;
236
325
  }
237
326
 
238
327
  - (void)setOnDeselect:(RCTDirectEventBlock)onDeselect {
239
- _realMarker.onDeselect = onDeselect;
328
+ _realMarker.onDeselect = onDeselect;
329
+ _onDeselect = onDeselect;
240
330
  }
241
331
 
242
332
  - (RCTDirectEventBlock)onDeselect {
243
- return _realMarker.onDeselect;
333
+ return _realMarker.onDeselect;
244
334
  }
245
335
 
246
336
  - (void)setOpacity:(double)opacity
247
337
  {
248
- _realMarker.opacity = opacity;
338
+ _realMarker.opacity = opacity;
339
+ _opacity = opacity;
249
340
  }
250
341
 
251
342
  - (void)setImageSrc:(NSString *)imageSrc
252
343
  {
253
- _imageSrc = imageSrc;
254
-
255
- if (_reloadImageCancellationBlock) {
256
- _reloadImageCancellationBlock();
257
- _reloadImageCancellationBlock = nil;
258
- }
259
-
260
- if (!_imageSrc) {
261
- if (_iconImageView) [_iconImageView removeFromSuperview];
262
- return;
263
- }
264
-
265
- if (!_iconImageView) {
266
- // prevent glitch with marker (cf. https://github.com/react-native-maps/react-native-maps/issues/738)
267
- UIImageView *empyImageView = [[UIImageView alloc] init];
268
- _iconImageView = empyImageView;
269
- [self iconViewInsertSubview:_iconImageView atIndex:0];
270
- }
271
-
272
- _reloadImageCancellationBlock = [[_bridge moduleForName:@"ImageLoader"] loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc]
273
- size:self.bounds.size
274
- scale:RCTScreenScale()
275
- clipped:YES
276
- resizeMode:RCTResizeModeCenter
277
- progressBlock:nil
278
- partialLoadBlock:nil
279
- completionBlock:^(NSError *error, UIImage *image) {
280
- if (error) {
281
- // TODO(lmr): do something with the error?
282
- NSLog(@"%@", error);
283
- }
284
- dispatch_async(dispatch_get_main_queue(), ^{
285
-
286
- // TODO(gil): This way allows different image sizes
287
- if (self->_iconImageView) [self->_iconImageView removeFromSuperview];
288
-
289
- // ... but this way is more efficient?
290
- // if (_iconImageView) {
291
- // [_iconImageView setImage:image];
292
- // return;
293
- // }
294
-
295
- UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
296
-
297
- // TODO: w,h or pixel density could be a prop.
298
- float density = 1;
299
- float w = image.size.width/density;
300
- float h = image.size.height/density;
301
- CGRect bounds = CGRectMake(0, 0, w, h);
302
-
303
- imageView.contentMode = UIViewContentModeScaleAspectFit;
304
- [imageView setFrame:bounds];
305
-
306
- // NOTE: sizeToFit doesn't work instead. Not sure why.
307
- // TODO: Doing it this way is not ideal because it causes things to reshuffle
308
- // when the image loads IF the image is larger than the UIView.
309
- // Shouldn't required images have size info automatically via RN?
310
- CGRect selfBounds = unionRect(bounds, self.bounds);
311
- [self setFrame:selfBounds];
312
-
313
- self->_iconImageView = imageView;
314
- [self iconViewInsertSubview:imageView atIndex:0];
315
- });
316
- }];
344
+ _imageSrc = imageSrc;
345
+
346
+ if (_reloadImageCancellationBlock) {
347
+ _reloadImageCancellationBlock();
348
+ _reloadImageCancellationBlock = nil;
349
+ }
350
+
351
+ if (!_imageSrc) {
352
+ if (_iconImageView) [_iconImageView removeFromSuperview];
353
+ return;
354
+ }
355
+
356
+ if (!_iconImageView) {
357
+ // prevent glitch with marker (cf. https://github.com/react-native-maps/react-native-maps/issues/738)
358
+ UIImageView *empyImageView = [[UIImageView alloc] init];
359
+ _iconImageView = empyImageView;
360
+ [self iconViewInsertSubview:_iconImageView atIndex:0];
361
+ }
362
+
363
+ _reloadImageCancellationBlock = [[_bridge moduleForName:@"ImageLoader"] loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc]
364
+ size:self.bounds.size
365
+ scale:RCTScreenScale()
366
+ clipped:YES
367
+ resizeMode:RCTResizeModeCenter
368
+ progressBlock:nil
369
+ partialLoadBlock:nil
370
+ completionBlock:^(NSError *error, UIImage *image) {
371
+ if (error) {
372
+ // TODO(lmr): do something with the error?
373
+ NSLog(@"%@", error);
374
+ }
375
+ dispatch_async(dispatch_get_main_queue(), ^{
376
+
377
+ // TODO(gil): This way allows different image sizes
378
+ if (self->_iconImageView) [self->_iconImageView removeFromSuperview];
379
+
380
+ // ... but this way is more efficient?
381
+ // if (_iconImageView) {
382
+ // [_iconImageView setImage:image];
383
+ // return;
384
+ // }
385
+
386
+ UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
387
+
388
+ // TODO: w,h or pixel density could be a prop.
389
+ float density = 1;
390
+ float w = image.size.width/density;
391
+ float h = image.size.height/density;
392
+ CGRect bounds = CGRectMake(0, 0, w, h);
393
+
394
+ imageView.contentMode = UIViewContentModeScaleAspectFit;
395
+ [imageView setFrame:bounds];
396
+
397
+ // NOTE: sizeToFit doesn't work instead. Not sure why.
398
+ // TODO: Doing it this way is not ideal because it causes things to reshuffle
399
+ // when the image loads IF the image is larger than the UIView.
400
+ // Shouldn't required images have size info automatically via RN?
401
+ CGRect selfBounds = unionRect(bounds, self.bounds);
402
+ [self setFrame:selfBounds];
403
+
404
+ self->_iconImageView = imageView;
405
+ [self iconViewInsertSubview:imageView atIndex:0];
406
+ });
407
+ }];
317
408
  }
318
409
 
319
410
  - (void)setIconSrc:(NSString *)iconSrc
320
411
  {
321
- _iconSrc = iconSrc;
322
-
323
- if (_reloadImageCancellationBlock) {
324
- _reloadImageCancellationBlock();
325
- _reloadImageCancellationBlock = nil;
326
- }
327
-
328
- if (!_realMarker.icon) {
329
- // prevent glitch with marker (cf. https://github.com/react-native-maps/react-native-maps/issues/3657)
330
- UIImage *emptyImage = [[UIImage alloc] init];
331
- _realMarker.icon = emptyImage;
332
- }
333
-
334
- _reloadImageCancellationBlock =
335
- [[_bridge moduleForName:@"ImageLoader"] loadImageWithURLRequest:[RCTConvert NSURLRequest:_iconSrc]
336
- size:self.bounds.size
337
- scale:RCTScreenScale()
338
- clipped:YES
339
- resizeMode:RCTResizeModeCenter
340
- progressBlock:nil
341
- partialLoadBlock:nil
342
- completionBlock:^(NSError *error, UIImage *image) {
343
- if (error) {
344
- // TODO(lmr): do something with the error?
345
- NSLog(@"%@", error);
346
- }
347
- dispatch_async(dispatch_get_main_queue(), ^{
348
- self->_realMarker.icon = image;
349
- });
350
- }];
412
+ _iconSrc = iconSrc;
413
+
414
+ if (_reloadImageCancellationBlock) {
415
+ _reloadImageCancellationBlock();
416
+ _reloadImageCancellationBlock = nil;
417
+ }
418
+
419
+ if (!_realMarker.icon) {
420
+ // prevent glitch with marker (cf. https://github.com/react-native-maps/react-native-maps/issues/3657)
421
+ UIImage *emptyImage = [[UIImage alloc] init];
422
+ _realMarker.icon = emptyImage;
423
+ }
424
+
425
+ _reloadImageCancellationBlock =
426
+ [[_bridge moduleForName:@"ImageLoader"] loadImageWithURLRequest:[RCTConvert NSURLRequest:_iconSrc]
427
+ size:self.bounds.size
428
+ scale:RCTScreenScale()
429
+ clipped:YES
430
+ resizeMode:RCTResizeModeCenter
431
+ progressBlock:nil
432
+ partialLoadBlock:nil
433
+ completionBlock:^(NSError *error, UIImage *image) {
434
+ if (error) {
435
+ // TODO(lmr): do something with the error?
436
+ NSLog(@"%@", error);
437
+ }
438
+ dispatch_async(dispatch_get_main_queue(), ^{
439
+ self->_realMarker.icon = image;
440
+ });
441
+ }];
351
442
  }
352
443
 
353
444
  - (void)setTitle:(NSString *)title {
354
- _realMarker.title = [title copy];
445
+ _realMarker.title = [title copy];
446
+ _title = title;
355
447
  }
356
448
 
357
449
  - (NSString *)title {
358
- return _realMarker.title;
450
+ return _realMarker.title;
359
451
  }
360
452
 
361
453
  - (void)setSubtitle:(NSString *)subtitle {
362
- _realMarker.snippet = subtitle;
454
+ _realMarker.snippet = subtitle;
455
+ _subtitle = subtitle;
363
456
  }
364
457
 
365
458
  - (NSString *)subtitle {
366
- return _realMarker.snippet;
459
+ return _realMarker.snippet;
367
460
  }
368
461
 
369
462
  - (void)setPinColor:(UIColor *)pinColor {
370
- _pinColor = pinColor;
371
- _realMarker.icon = [GMSMarker markerImageWithColor:pinColor];
463
+ _pinColor = pinColor;
464
+ _realMarker.icon = [GMSMarker markerImageWithColor:pinColor];
372
465
  }
373
466
 
374
467
  - (void)setAnchor:(CGPoint)anchor {
375
- _anchor = anchor;
376
- _realMarker.groundAnchor = anchor;
468
+ _anchor = anchor;
469
+ _realMarker.groundAnchor = anchor;
377
470
  }
378
471
 
379
472
  - (void)setCalloutAnchor:(CGPoint)calloutAnchor {
380
- _calloutAnchor = calloutAnchor;
381
- _realMarker.infoWindowAnchor = calloutAnchor;
473
+ _calloutAnchor = calloutAnchor;
474
+ _realMarker.infoWindowAnchor = calloutAnchor;
382
475
  }
383
476
 
384
477
 
385
478
  - (void)setZIndex:(NSInteger)zIndex
386
479
  {
387
- _zIndex = zIndex;
388
- _realMarker.zIndex = (int)zIndex;
480
+ _zIndex = zIndex;
481
+ _realMarker.zIndex = (int)zIndex;
389
482
  }
390
483
 
391
484
  - (void)setDraggable:(BOOL)draggable {
392
- _realMarker.draggable = draggable;
485
+ _realMarker.draggable = draggable;
486
+ _draggable = draggable;
393
487
  }
394
488
 
395
489
  - (BOOL)draggable {
396
- return _realMarker.draggable;
490
+ return _realMarker.draggable;
397
491
  }
398
492
 
399
493
  - (void)setTappable:(BOOL)tappable {
400
- _realMarker.tappable = tappable;
494
+ _realMarker.tappable = tappable;
495
+ _tappable = tappable;
401
496
  }
402
497
 
403
498
  - (BOOL)tappable {
404
- return _realMarker.tappable;
499
+ return _realMarker.tappable;
405
500
  }
406
501
 
407
502
  - (void)setFlat:(BOOL)flat {
408
- _realMarker.flat = flat;
503
+ _realMarker.flat = flat;
504
+ _flat = flat;
409
505
  }
410
506
 
411
507
  - (BOOL)flat {
412
- return _realMarker.flat;
508
+ return _realMarker.flat;
413
509
  }
414
510
 
415
511
  - (void)setTracksViewChanges:(BOOL)tracksViewChanges {
416
- _realMarker.tracksViewChanges = tracksViewChanges;
512
+ _realMarker.tracksViewChanges = tracksViewChanges;
417
513
  }
418
514
 
419
515
  - (BOOL)tracksViewChanges {
420
- return _realMarker.tracksViewChanges;
516
+ return _realMarker.tracksViewChanges;
421
517
  }
422
518
 
423
519
  - (void)setTracksInfoWindowChanges:(BOOL)tracksInfoWindowChanges {
424
- _realMarker.tracksInfoWindowChanges = tracksInfoWindowChanges;
520
+ _realMarker.tracksInfoWindowChanges = tracksInfoWindowChanges;
425
521
  }
426
522
 
427
523
  - (BOOL)tracksInfoWindowChanges {
428
- return _realMarker.tracksInfoWindowChanges;
524
+ return _realMarker.tracksInfoWindowChanges;
429
525
  }
430
526
 
431
527
 
@@ -434,17 +530,17 @@ CGRect unionRect(CGRect a, CGRect b) {
434
530
  CGPoint position = [self.realMarker.map.projection pointForCoordinate:coordinate];
435
531
 
436
532
  return @{
437
- @"id": self.identifier ?: @"unknown",
438
- @"position": @{
439
- @"x": @(position.x),
440
- @"y": @(position.y),
441
- },
442
- @"coordinate": @{
443
- @"latitude": @(coordinate.latitude),
444
- @"longitude": @(coordinate.longitude),
445
- },
446
- @"action": action,
447
- };
533
+ @"id": self.identifier ?: @"unknown",
534
+ @"position": @{
535
+ @"x": @(position.x),
536
+ @"y": @(position.y),
537
+ },
538
+ @"coordinate": @{
539
+ @"latitude": @(coordinate.latitude),
540
+ @"longitude": @(coordinate.longitude),
541
+ },
542
+ @"action": action,
543
+ };
448
544
  }
449
545
 
450
546
  - (id)makeEventData {
@@ -389,8 +389,11 @@ using namespace facebook::react;
389
389
  } else {
390
390
  [_pendingInsertsSubviews setObject:paperView forKey:[NSNumber numberWithInteger:index]];
391
391
  }
392
+ } else {
393
+ [_view insertReactSubview:childComponentView atIndex:index];
392
394
  }
393
395
  }
396
+
394
397
  - (void) unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
395
398
  {
396
399
  id<RCTComponent> paperView = [childComponentView getPaperViewFromChildComponentView];
@@ -400,8 +403,20 @@ using namespace facebook::react;
400
403
  } else {
401
404
  [_pendingInsertsSubviews removeObjectForKey:[NSNumber numberWithInteger:index]];
402
405
  }
406
+ } else {
407
+ [_view removeReactSubview:childComponentView];
403
408
  }
404
409
  }
410
+ - (void) prepareForRecycle
411
+ {
412
+ [super prepareForRecycle];
413
+ static const auto defaultProps = std::make_shared<const RNMapsGoogleMapViewProps>();
414
+ _props = defaultProps;
415
+ _legacyMapManager = [[AIRGoogleMapManager alloc] init];
416
+ _pendingInsertsSubviews = [NSMutableDictionary new];
417
+ [_view removeFromSuperview];
418
+ _view = nil;
419
+ }
405
420
 
406
421
 
407
422
  - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
package/lib/MapView.js CHANGED
@@ -55,7 +55,7 @@ class MapView extends React.Component {
55
55
  this.map = React.createRef();
56
56
  this.fabricMap = React.createRef();
57
57
  this.state = {
58
- isReady: react_native_1.Platform.OS === 'ios',
58
+ isReady: false,
59
59
  };
60
60
  this._onMapReady = this._onMapReady.bind(this);
61
61
  this._onChange = this._onChange.bind(this);
@@ -348,7 +348,7 @@ class MapView extends React.Component {
348
348
  if (react_native_1.Platform.OS === 'ios') {
349
349
  // Define props specifically for MapFabricNativeProps
350
350
  /* eslint-disable @typescript-eslint/no-unused-vars */
351
- const { onCalloutPress, onIndoorBuildingFocused, onKmlReady, onLongPress, onMarkerDeselect, onMarkerPress, onMarkerSelect, onRegionChangeStart, onRegionChange, onRegionChangeComplete, onPress, minZoomLevel, maxZoomLevel, region, provider, ...restProps } = this.props;
351
+ const { onCalloutPress, onIndoorBuildingFocused, onKmlReady, onLongPress, onMarkerDeselect, onMarkerPress, onMarkerSelect, onRegionChangeStart, onRegionChange, onRegionChangeComplete, onPress, minZoomLevel, maxZoomLevel, region, provider, children, ...restProps } = this.props;
352
352
  /* eslint-enable @typescript-eslint/no-unused-vars */
353
353
  const userInterfaceStyle = this.props.userInterfaceStyle || 'system';
354
354
  const props = {
@@ -379,14 +379,19 @@ class MapView extends React.Component {
379
379
  props.initialCamera = this.props.initialCamera;
380
380
  props.onLayout = this.props.onLayout;
381
381
  }
382
+ const childrenNodes = this.state.isReady ? children : null;
382
383
  if (provider === 'google') {
383
384
  return (<decorateMapComponent_1.ProviderContext.Provider value={this.props.provider}>
384
- <FabricGoogleMap {...props} ref={this.fabricMap}/>
385
+ <FabricGoogleMap {...props} ref={this.fabricMap}>
386
+ {childrenNodes}
387
+ </FabricGoogleMap>
385
388
  </decorateMapComponent_1.ProviderContext.Provider>);
386
389
  }
387
390
  else {
388
391
  return (<decorateMapComponent_1.ProviderContext.Provider value={this.props.provider}>
389
- <FabricMap {...props} ref={this.fabricMap}/>
392
+ <FabricMap {...props} ref={this.fabricMap}>
393
+ {childrenNodes}
394
+ </FabricMap>
390
395
  </decorateMapComponent_1.ProviderContext.Provider>);
391
396
  }
392
397
  }
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "main": "lib/index.js",
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.11",
8
+ "version": "1.21.0-alpha.12",
9
9
  "license": "MIT",
10
10
  "scripts": {
11
11
  "lint": "eslint . --max-warnings 0",
@@ -9,7 +9,7 @@ Pod::Spec.new do |s|
9
9
  s.authors = package["author"]
10
10
  s.homepage = package["homepage"]
11
11
  s.license = package["license"]
12
- s.platform = :ios, "11.0"
12
+ s.platform = :ios, "12.0"
13
13
 
14
14
  s.source = { :git => "https://github.com/react-native-maps/react-native-maps.git", :tag=> "v#{s.version}" }
15
15
  s.source_files = "ios/AirMaps/**/*.{h,m,mm,swift}"