react-native-maps 1.21.0-alpha.28 → 1.21.0-alpha.29
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.
- package/ios/AirMaps/AIRMap.m +30 -0
- package/ios/AirMaps/AIRMapMarker.m +112 -111
- package/package.json +1 -1
package/ios/AirMaps/AIRMap.m
CHANGED
|
@@ -90,6 +90,7 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
90
90
|
self.compassOffset = CGPointMake(0, 0);
|
|
91
91
|
self.legacyZoomConstraintsEnabled = YES;
|
|
92
92
|
_initialized = YES;
|
|
93
|
+
[self listenToMemoryWarnings];
|
|
93
94
|
}
|
|
94
95
|
return self;
|
|
95
96
|
}
|
|
@@ -735,6 +736,35 @@ const NSInteger AIRMapMaxZoomLevel = 20;
|
|
|
735
736
|
}
|
|
736
737
|
}
|
|
737
738
|
|
|
739
|
+
- (void) listenToMemoryWarnings
|
|
740
|
+
{
|
|
741
|
+
__weak typeof(self) weakSelf = self;
|
|
742
|
+
static dispatch_once_t onceToken;
|
|
743
|
+
static dispatch_source_t source;
|
|
744
|
+
dispatch_once(&onceToken, ^{
|
|
745
|
+
source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, DISPATCH_MEMORYPRESSURE_WARN|DISPATCH_MEMORYPRESSURE_CRITICAL, dispatch_get_main_queue());
|
|
746
|
+
dispatch_source_set_event_handler(source, ^{
|
|
747
|
+
[weakSelf handleMemoryWarning];
|
|
748
|
+
});
|
|
749
|
+
dispatch_resume(source);
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
/*
|
|
753
|
+
hacky way to release all cache
|
|
754
|
+
this is our last chance to release cache before app crash
|
|
755
|
+
*/
|
|
756
|
+
- (void) handleMemoryWarning
|
|
757
|
+
{
|
|
758
|
+
NSLog(@"handleMemoryWarning warning");
|
|
759
|
+
MKMapType type = self.mapType;
|
|
760
|
+
if (type == MKMapTypeSatellite){
|
|
761
|
+
self.mapType = MKMapTypeStandard;
|
|
762
|
+
} else {
|
|
763
|
+
self.mapType = MKMapTypeSatellite;
|
|
764
|
+
}
|
|
765
|
+
self.mapType = type;
|
|
766
|
+
}
|
|
767
|
+
|
|
738
768
|
- (void)updateLegalLabelInsets {
|
|
739
769
|
if (_legalLabel) {
|
|
740
770
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
@@ -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,22 +52,22 @@ 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
|
-
|
|
65
|
-
|
|
64
|
+
isnan(bounds.origin.x) || isnan(bounds.origin.y) ||
|
|
65
|
+
isnan(bounds.size.width) || isnan(bounds.size.height)) {
|
|
66
66
|
RCTLogError(@"Invalid layout for (%@)%@. position: %@. bounds: %@",
|
|
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,36 +102,36 @@ 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
|
+
|
|
119
119
|
return _pinView;
|
|
120
120
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
124
|
if (_markerView == nil && !_useLegacyPinView) {
|
|
125
125
|
_markerView = [[MKMarkerAnnotationView alloc] initWithAnnotation:self reuseIdentifier: nil];
|
|
126
126
|
[self addGestureRecognizerToView:_markerView];
|
|
127
127
|
_markerView.annotation = self;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
128
|
+
|
|
129
|
+
_markerView.draggable = self.draggable;
|
|
130
|
+
_markerView.layer.zPosition = self.zIndex;
|
|
131
|
+
_markerView.markerTintColor = self.pinColor;
|
|
132
|
+
_markerView.titleVisibility = self.titleVisibility ?: MKFeatureVisibilityHidden;
|
|
133
|
+
_markerView.subtitleVisibility = self.subtitleVisibility ?: MKFeatureVisibilityHidden;
|
|
134
|
+
|
|
135
135
|
}
|
|
136
136
|
return _markerView ?: _pinView;
|
|
137
137
|
} else {
|
|
@@ -147,14 +147,14 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
147
147
|
- (void)fillCalloutView:(SMCalloutView *)calloutView
|
|
148
148
|
{
|
|
149
149
|
// Set everything necessary on the calloutView before it becomes visible.
|
|
150
|
-
|
|
150
|
+
|
|
151
151
|
// Apply the MKAnnotationView's desired calloutOffset (from the top-middle of the view)
|
|
152
|
-
|
|
152
|
+
if ([self shouldUsePinView] && !_hasSetCalloutOffset && _useLegacyPinView) {
|
|
153
153
|
calloutView.calloutOffset = CGPointMake(-8,0);
|
|
154
154
|
} else {
|
|
155
155
|
calloutView.calloutOffset = self.calloutOffset;
|
|
156
156
|
}
|
|
157
|
-
|
|
157
|
+
|
|
158
158
|
if (self.calloutView) {
|
|
159
159
|
calloutView.title = nil;
|
|
160
160
|
calloutView.subtitle = nil;
|
|
@@ -167,13 +167,13 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
167
167
|
// as a result, we use the default "masked" background view.
|
|
168
168
|
calloutView.backgroundView = [SMCalloutMaskedBackgroundView new];
|
|
169
169
|
}
|
|
170
|
-
|
|
170
|
+
|
|
171
171
|
// when this is set, the callout's content will be whatever react views the user has put as the callout's
|
|
172
172
|
// children.
|
|
173
173
|
calloutView.contentView = self.calloutView;
|
|
174
|
-
|
|
174
|
+
|
|
175
175
|
} else {
|
|
176
|
-
|
|
176
|
+
|
|
177
177
|
// if there is no calloutView, it means the user wants to use the default callout behavior with title/subtitle
|
|
178
178
|
// pairs.
|
|
179
179
|
calloutView.title = self.title;
|
|
@@ -187,37 +187,37 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
187
187
|
{
|
|
188
188
|
_calloutIsOpen = YES;
|
|
189
189
|
[self setZIndex:_zIndexBeforeOpen];
|
|
190
|
-
|
|
190
|
+
|
|
191
191
|
MKAnnotationView *annotationView = [self getAnnotationView];
|
|
192
|
-
|
|
192
|
+
|
|
193
193
|
[self setSelected:YES animated:NO];
|
|
194
194
|
[self.map selectAnnotation:self animated:NO];
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
id event = @{
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
197
|
+
@"action": @"marker-select",
|
|
198
|
+
@"id": self.identifier ?: @"unknown",
|
|
199
|
+
@"coordinate": @{
|
|
200
|
+
@"latitude": @(self.coordinate.latitude),
|
|
201
|
+
@"longitude": @(self.coordinate.longitude)
|
|
202
|
+
}
|
|
203
203
|
};
|
|
204
|
-
|
|
204
|
+
|
|
205
205
|
if (self.map.onMarkerSelect) self.map.onMarkerSelect(event);
|
|
206
206
|
if (self.onSelect) self.onSelect(event);
|
|
207
|
-
|
|
207
|
+
|
|
208
208
|
if (![self shouldShowCalloutView]) {
|
|
209
209
|
// no callout to show
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
212
|
-
|
|
212
|
+
|
|
213
213
|
[self fillCalloutView:self.map.calloutView];
|
|
214
|
-
|
|
214
|
+
|
|
215
215
|
// This is where we present our custom callout view... MapKit's built-in callout doesn't have the flexibility
|
|
216
216
|
// we need, but a lot of work was done by Nick Farina to make this identical to MapKit's built-in.
|
|
217
217
|
[self.map.calloutView presentCalloutFromRect:annotationView.bounds
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
218
|
+
inView:annotationView
|
|
219
|
+
constrainedToView:self.map
|
|
220
|
+
animated:YES];
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
#pragma mark - Tap Gesture & Events.
|
|
@@ -239,12 +239,12 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
239
239
|
- (void)_handleTap:(UITapGestureRecognizer *)recognizer {
|
|
240
240
|
AIRMapMarker *marker = self;
|
|
241
241
|
if (!marker) return;
|
|
242
|
-
|
|
242
|
+
|
|
243
243
|
if (marker.selected) {
|
|
244
244
|
CGPoint touchPoint = [recognizer locationInView:marker.map.calloutView];
|
|
245
245
|
CGRect bubbleFrame = [self.calloutView convertRect:marker.map.calloutView.bounds toView:marker.map];
|
|
246
246
|
CGPoint touchPointReal = [recognizer locationInView:self.calloutView];
|
|
247
|
-
|
|
247
|
+
|
|
248
248
|
UIView *calloutView = [marker.map.calloutView hitTest:touchPoint withEvent:nil];
|
|
249
249
|
if (calloutView) {
|
|
250
250
|
// the callout (or its subview) got clicked, not the marker
|
|
@@ -258,22 +258,22 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
258
258
|
}
|
|
259
259
|
tmp = tmp.superview;
|
|
260
260
|
}
|
|
261
|
-
|
|
261
|
+
|
|
262
262
|
id event = @{
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
263
|
+
@"action": calloutSubview ? @"callout-inside-press" : @"callout-press",
|
|
264
|
+
@"id": marker.identifier ?: @"unknown",
|
|
265
|
+
@"point": @{
|
|
266
|
+
@"x": @(touchPointReal.x),
|
|
267
|
+
@"y": @(touchPointReal.y),
|
|
268
|
+
},
|
|
269
|
+
@"frame": @{
|
|
270
|
+
@"x": @(bubbleFrame.origin.x),
|
|
271
|
+
@"y": @(bubbleFrame.origin.y),
|
|
272
|
+
@"width": @(bubbleFrame.size.width),
|
|
273
|
+
@"height": @(bubbleFrame.size.height),
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
277
|
if (calloutSubview) calloutSubview.onPress(event);
|
|
278
278
|
if (marker.onCalloutPress) marker.onCalloutPress(event);
|
|
279
279
|
if (marker.calloutView && marker.calloutView.onPress) marker.calloutView.onPress(event);
|
|
@@ -281,25 +281,25 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
281
281
|
return;
|
|
282
282
|
}
|
|
283
283
|
}
|
|
284
|
-
|
|
284
|
+
|
|
285
285
|
// the actual marker got clicked
|
|
286
286
|
CGPoint touchPointReal = [recognizer locationInView:self.calloutView];
|
|
287
287
|
id event = @{
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
288
|
+
@"action": @"marker-press",
|
|
289
|
+
@"id": marker.identifier ?: @"unknown",
|
|
290
|
+
@"coordinate": @{
|
|
291
|
+
@"latitude": @(marker.coordinate.latitude),
|
|
292
|
+
@"longitude": @(marker.coordinate.longitude)
|
|
293
|
+
},
|
|
294
|
+
@"position": @{
|
|
295
|
+
@"x": @(touchPointReal.x),
|
|
296
|
+
@"y": @(touchPointReal.y),
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
300
|
if (marker.onPress) marker.onPress(event);
|
|
301
301
|
if (marker.map.onMarkerPress) marker.map.onMarkerPress(event);
|
|
302
|
-
|
|
302
|
+
|
|
303
303
|
[marker.map selectAnnotation:marker animated:NO];
|
|
304
304
|
}
|
|
305
305
|
|
|
@@ -309,19 +309,19 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
309
309
|
[self setZIndex:_zIndexBeforeOpen];
|
|
310
310
|
// hide the callout view
|
|
311
311
|
[self.map.calloutView dismissCalloutAnimated:YES];
|
|
312
|
-
|
|
312
|
+
|
|
313
313
|
[self setSelected:NO animated:NO];
|
|
314
314
|
[self.map deselectAnnotation:self animated:NO];
|
|
315
|
-
|
|
315
|
+
|
|
316
316
|
id event = @{
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
317
|
+
@"action": @"marker-deselect",
|
|
318
|
+
@"id": self.identifier ?: @"unknown",
|
|
319
|
+
@"coordinate": @{
|
|
320
|
+
@"latitude": @(self.coordinate.latitude),
|
|
321
|
+
@"longitude": @(self.coordinate.longitude)
|
|
322
|
+
}
|
|
323
323
|
};
|
|
324
|
-
|
|
324
|
+
|
|
325
325
|
if (self.map.onMarkerDeselect) self.map.onMarkerDeselect(event);
|
|
326
326
|
if (self.onDeselect) self.onDeselect(event);
|
|
327
327
|
}
|
|
@@ -344,41 +344,42 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
344
344
|
|
|
345
345
|
- (void)setOpacity:(double)opacity
|
|
346
346
|
{
|
|
347
|
-
|
|
347
|
+
[self setAlpha:opacity];
|
|
348
348
|
}
|
|
349
349
|
|
|
350
350
|
- (void)setImageSrc:(NSString *)imageSrc
|
|
351
351
|
{
|
|
352
352
|
_imageSrc = imageSrc;
|
|
353
|
-
|
|
353
|
+
|
|
354
354
|
if (_reloadImageCancellationBlock) {
|
|
355
355
|
_reloadImageCancellationBlock();
|
|
356
356
|
_reloadImageCancellationBlock = nil;
|
|
357
357
|
}
|
|
358
|
-
|
|
358
|
+
__weak __typeof(self) weakSelf = self;
|
|
359
|
+
|
|
359
360
|
_reloadImageCancellationBlock = [[[RCTBridge currentBridge] moduleForName:@"ImageLoader"] loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc]
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
361
|
+
size:self.bounds.size
|
|
362
|
+
scale:RCTScreenScale()
|
|
363
|
+
clipped:YES
|
|
364
|
+
resizeMode:RCTResizeModeCenter
|
|
365
|
+
progressBlock:nil
|
|
366
|
+
partialLoadBlock:nil
|
|
367
|
+
completionBlock:^(NSError *error, UIImage *image) {
|
|
368
|
+
if (error) {
|
|
369
|
+
// TODO(lmr): do something with the error?
|
|
370
|
+
NSLog(@"failed to load image: %@", error);
|
|
371
|
+
}
|
|
372
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
373
|
+
__strong __typeof(weakSelf) strongSelf = weakSelf;
|
|
374
|
+
strongSelf.image = image;
|
|
375
|
+
});
|
|
376
|
+
}];
|
|
376
377
|
}
|
|
377
378
|
|
|
378
379
|
- (void)setPinColor:(UIColor *)pinColor
|
|
379
380
|
{
|
|
380
381
|
_pinColor = pinColor;
|
|
381
|
-
|
|
382
|
+
|
|
382
383
|
if(_useLegacyPinView && [_pinView respondsToSelector:@selector(setPinTintColor:)]) {
|
|
383
384
|
_pinView.pinTintColor = _pinColor;
|
|
384
385
|
} else {
|
|
@@ -394,7 +395,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
394
395
|
}
|
|
395
396
|
|
|
396
397
|
- (BOOL)isSelected {
|
|
397
|
-
|
|
398
|
+
return _isPreselected || [super isSelected];
|
|
398
399
|
}
|
|
399
400
|
|
|
400
401
|
- (void)dealloc {
|
|
@@ -416,16 +417,16 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
416
417
|
NSLog(@"Animation already in progress. Rejecting new animation request.");
|
|
417
418
|
return;
|
|
418
419
|
}
|
|
419
|
-
|
|
420
|
+
|
|
420
421
|
// Mark as animating
|
|
421
422
|
_isAnimating = YES;
|
|
422
|
-
|
|
423
|
+
|
|
423
424
|
// Store animation parameters
|
|
424
425
|
_startCoordinate = self.coordinate;
|
|
425
426
|
_endCoordinate = newCoordinate;
|
|
426
427
|
_animationDuration = duration;
|
|
427
428
|
_animationStartTime = [NSDate timeIntervalSinceReferenceDate];
|
|
428
|
-
|
|
429
|
+
|
|
429
430
|
// Start a CADisplayLink
|
|
430
431
|
if (_displayLink) {
|
|
431
432
|
[_displayLink invalidate];
|
|
@@ -437,15 +438,15 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
437
438
|
- (void)updatePosition {
|
|
438
439
|
NSTimeInterval elapsed = [NSDate timeIntervalSinceReferenceDate] - _animationStartTime;
|
|
439
440
|
CGFloat progress = MIN(elapsed / _animationDuration, 1.0);
|
|
440
|
-
|
|
441
|
+
|
|
441
442
|
// Interpolate coordinates
|
|
442
443
|
CLLocationDegrees currentLatitude = _startCoordinate.latitude + progress * (_endCoordinate.latitude - _startCoordinate.latitude);
|
|
443
444
|
CLLocationDegrees currentLongitude = _startCoordinate.longitude + progress * (_endCoordinate.longitude - _startCoordinate.longitude);
|
|
444
|
-
|
|
445
|
+
|
|
445
446
|
// Update annotation's coordinate
|
|
446
447
|
CLLocationCoordinate2D currentCoordinate = CLLocationCoordinate2DMake(currentLatitude, currentLongitude);
|
|
447
448
|
[self setValue:[NSValue valueWithMKCoordinate:currentCoordinate] forKey:@"coordinate"];
|
|
448
|
-
|
|
449
|
+
|
|
449
450
|
// Stop the animation when complete
|
|
450
451
|
if (progress == 1.0) {
|
|
451
452
|
[_displayLink invalidate];
|
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.
|
|
8
|
+
"version": "1.21.0-alpha.29",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"lint": "eslint . --max-warnings 0",
|