react-native-maps 1.21.0-alpha.3 → 1.21.0-alpha.31
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/android/build.gradle +14 -3
- package/android/src/main/java/com/rnmaps/fabric/NativeAirMapsModule.java +51 -0
- package/android/src/main/java/com/rnmaps/maps/MapAirModulePackage.java +46 -0
- package/ios/AirGoogleMaps/AIRGoogleMap.h +8 -2
- package/ios/AirGoogleMaps/AIRGoogleMap.m +166 -11
- package/ios/AirGoogleMaps/AIRGoogleMapCircle.h +0 -1
- package/ios/AirGoogleMaps/AIRGoogleMapCircle.m +20 -11
- package/ios/AirGoogleMaps/AIRGoogleMapCoordinate.h +13 -0
- package/ios/AirGoogleMaps/AIRGoogleMapCoordinate.m +10 -0
- package/ios/AirGoogleMaps/AIRGoogleMapManager.h +7 -0
- package/ios/AirGoogleMaps/AIRGoogleMapManager.m +30 -119
- package/ios/AirGoogleMaps/AIRGoogleMapMarker.h +2 -0
- package/ios/AirGoogleMaps/AIRGoogleMapMarker.m +344 -243
- package/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m +0 -1
- package/ios/AirGoogleMaps/AIRGoogleMapOverlay.h +0 -1
- package/ios/AirGoogleMaps/AIRGoogleMapPolygon.h +5 -4
- package/ios/AirGoogleMaps/AIRGoogleMapPolygon.m +29 -2
- package/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m +3 -3
- package/ios/AirGoogleMaps/AIRGoogleMapPolyline.h +3 -2
- package/ios/AirGoogleMaps/AIRGoogleMapPolyline.m +2 -3
- package/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m +2 -2
- package/ios/AirGoogleMaps/AIRGoogleMapWMSTile.h +1 -1
- package/ios/AirGoogleMaps/AIRGoogleMapWMSTile.m +2 -2
- package/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h +3 -0
- package/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m +18 -0
- package/ios/AirGoogleMaps/RNMapsGoogleMapView.h +26 -0
- package/ios/AirGoogleMaps/RNMapsGoogleMapView.mm +599 -0
- package/ios/AirGoogleMaps/RNMapsGoogleMapViewManager.mm +25 -0
- package/ios/AirGoogleMaps/RNMapsGooglePolygonView.h +26 -0
- package/ios/AirGoogleMaps/RNMapsGooglePolygonView.mm +217 -0
- package/ios/AirGoogleMaps/RNMapsGooglePolygonViewManager.mm +25 -0
- package/ios/AirMaps/AIRMap.h +8 -4
- package/ios/AirMaps/AIRMap.m +226 -101
- package/ios/AirMaps/AIRMapManager.m +12 -21
- package/ios/AirMaps/AIRMapMarker.h +1 -0
- package/ios/AirMaps/AIRMapMarker.m +160 -103
- package/ios/AirMaps/Callout/SMCalloutView.m +1 -1
- package/ios/AirMaps/RCTConvert+AirMap.h +4 -0
- package/ios/AirMaps/RCTConvert+AirMap.m +2 -0
- package/ios/AirMaps/RNMapsAirModule.h +3 -0
- package/ios/AirMaps/RNMapsAirModule.mm +42 -172
- package/ios/AirMaps/RNMapsAirModuleDelegate.h +24 -0
- package/ios/AirMaps/RNMapsHostVewDelegate.h +17 -0
- package/ios/AirMaps/RNMapsMapView.h +6 -3
- package/ios/AirMaps/RNMapsMapView.mm +340 -334
- package/ios/AirMaps/RNMapsMarkerView.h +24 -0
- package/ios/AirMaps/RNMapsMarkerView.mm +404 -0
- package/ios/AirMaps/RNMapsMarkerViewManager.mm +21 -0
- package/ios/AirMaps/UIView +AirMap.m +20 -0
- package/ios/AirMaps/UIView+AirMap.h +11 -0
- package/lib/MapMarker.d.ts +3 -2
- package/lib/MapMarker.js +53 -9
- package/lib/MapMarkerNativeComponent.js +0 -2
- package/lib/MapOverlay.d.ts +1 -1
- package/lib/MapView.d.ts +5 -22
- package/lib/MapView.js +34 -21
- package/lib/{FabricMapView.d.ts → createFabricMap.d.ts} +7 -6
- package/lib/createFabricMap.js +175 -0
- package/lib/decorateMapComponent.js +18 -0
- package/lib/specs/NativeAirMapsModule.d.ts +2 -2
- package/lib/specs/NativeComponentGoogleMapView.d.ts +713 -0
- package/lib/specs/NativeComponentGoogleMapView.js +21 -0
- package/lib/specs/NativeComponentGooglePolygon.d.ts +75 -0
- package/lib/specs/NativeComponentGooglePolygon.js +9 -0
- package/lib/specs/NativeComponentMapView.d.ts +21 -45
- package/lib/specs/NativeComponentMarker.d.ts +246 -0
- package/lib/specs/NativeComponentMarker.js +21 -0
- package/package.json +7 -7
- package/react-native-maps.podspec +1 -1
- package/lib/FabricMapView.js +0 -175
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
#import <React/RCTImageLoaderProtocol.h>
|
|
15
15
|
#import <React/RCTUtils.h>
|
|
16
16
|
#import <React/UIView+React.h>
|
|
17
|
+
#import <React/RCTImageLoader.h>
|
|
18
|
+
#import <React/RCTBridge+Private.h>
|
|
17
19
|
|
|
18
20
|
NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
19
21
|
|
|
@@ -28,6 +30,13 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
28
30
|
BOOL _calloutIsOpen;
|
|
29
31
|
NSInteger _zIndexBeforeOpen;
|
|
30
32
|
BOOL _useLegacyPinView;
|
|
33
|
+
|
|
34
|
+
CADisplayLink *_displayLink;
|
|
35
|
+
CLLocationCoordinate2D _startCoordinate;
|
|
36
|
+
CLLocationCoordinate2D _endCoordinate;
|
|
37
|
+
NSTimeInterval _animationStartTime;
|
|
38
|
+
NSTimeInterval _animationDuration;
|
|
39
|
+
BOOL _isAnimating;
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
- (instancetype)initWithFrame:(CGRect)frame {
|
|
@@ -43,22 +52,22 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
43
52
|
// Make sure we use the image size when available
|
|
44
53
|
CGSize size = self.image ? self.image.size : frame.size;
|
|
45
54
|
CGRect bounds = {CGPointZero, size};
|
|
46
|
-
|
|
55
|
+
|
|
47
56
|
// The MapView is basically in charge of figuring out the center position of the marker view. If the view changed in
|
|
48
57
|
// height though, we need to compensate in such a way that the bottom of the marker stays at the same spot on the
|
|
49
58
|
// map.
|
|
50
59
|
CGFloat dy = (bounds.size.height - self.bounds.size.height) / 2;
|
|
51
60
|
CGPoint center = (CGPoint){ self.center.x, self.center.y - dy };
|
|
52
|
-
|
|
61
|
+
|
|
53
62
|
// Avoid crashes due to nan coords
|
|
54
63
|
if (isnan(center.x) || isnan(center.y) ||
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
isnan(bounds.origin.x) || isnan(bounds.origin.y) ||
|
|
65
|
+
isnan(bounds.size.width) || isnan(bounds.size.height)) {
|
|
57
66
|
RCTLogError(@"Invalid layout for (%@)%@. position: %@. bounds: %@",
|
|
58
|
-
|
|
67
|
+
self.reactTag, self, NSStringFromCGPoint(center), NSStringFromCGRect(bounds));
|
|
59
68
|
return;
|
|
60
69
|
}
|
|
61
|
-
|
|
70
|
+
|
|
62
71
|
self.center = center;
|
|
63
72
|
self.bounds = bounds;
|
|
64
73
|
}
|
|
@@ -68,6 +77,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
68
77
|
self.calloutView = (AIRMapCallout *)subview;
|
|
69
78
|
} else {
|
|
70
79
|
[super insertReactSubview:(UIView *)subview atIndex:atIndex];
|
|
80
|
+
[self addSubview:subview];
|
|
71
81
|
}
|
|
72
82
|
}
|
|
73
83
|
- (void) setFrame:(CGRect)frame {
|
|
@@ -84,6 +94,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
84
94
|
self.calloutView = nil;
|
|
85
95
|
} else {
|
|
86
96
|
[super removeReactSubview:(UIView *)subview];
|
|
97
|
+
[(UIView *) subview removeFromSuperview];
|
|
87
98
|
}
|
|
88
99
|
}
|
|
89
100
|
|
|
@@ -91,36 +102,36 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
91
102
|
{
|
|
92
103
|
if ([self shouldUsePinView]) {
|
|
93
104
|
// In this case, we want to render a platform "default" legacy marker.
|
|
94
|
-
|
|
95
|
-
|
|
105
|
+
|
|
106
|
+
|
|
96
107
|
if (_pinView == nil && _useLegacyPinView) {
|
|
97
108
|
_pinView = [[MKPinAnnotationView alloc] initWithAnnotation:self reuseIdentifier: nil];
|
|
98
109
|
[self addGestureRecognizerToView:_pinView];
|
|
99
110
|
_pinView.annotation = self;
|
|
100
|
-
|
|
111
|
+
|
|
101
112
|
if ([_pinView respondsToSelector:@selector(setPinTintColor:)]) {
|
|
102
113
|
_pinView.pinTintColor = self.pinColor;
|
|
103
114
|
}
|
|
104
|
-
|
|
115
|
+
|
|
105
116
|
_pinView.draggable = self.draggable;
|
|
106
117
|
_pinView.layer.zPosition = self.zIndex;
|
|
107
|
-
|
|
118
|
+
|
|
108
119
|
return _pinView;
|
|
109
120
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
113
124
|
if (_markerView == nil && !_useLegacyPinView) {
|
|
114
125
|
_markerView = [[MKMarkerAnnotationView alloc] initWithAnnotation:self reuseIdentifier: nil];
|
|
115
126
|
[self addGestureRecognizerToView:_markerView];
|
|
116
127
|
_markerView.annotation = self;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
+
|
|
124
135
|
}
|
|
125
136
|
return _markerView ?: _pinView;
|
|
126
137
|
} else {
|
|
@@ -136,14 +147,14 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
136
147
|
- (void)fillCalloutView:(SMCalloutView *)calloutView
|
|
137
148
|
{
|
|
138
149
|
// Set everything necessary on the calloutView before it becomes visible.
|
|
139
|
-
|
|
150
|
+
|
|
140
151
|
// Apply the MKAnnotationView's desired calloutOffset (from the top-middle of the view)
|
|
141
|
-
|
|
152
|
+
if ([self shouldUsePinView] && !_hasSetCalloutOffset && _useLegacyPinView) {
|
|
142
153
|
calloutView.calloutOffset = CGPointMake(-8,0);
|
|
143
154
|
} else {
|
|
144
155
|
calloutView.calloutOffset = self.calloutOffset;
|
|
145
156
|
}
|
|
146
|
-
|
|
157
|
+
|
|
147
158
|
if (self.calloutView) {
|
|
148
159
|
calloutView.title = nil;
|
|
149
160
|
calloutView.subtitle = nil;
|
|
@@ -156,13 +167,13 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
156
167
|
// as a result, we use the default "masked" background view.
|
|
157
168
|
calloutView.backgroundView = [SMCalloutMaskedBackgroundView new];
|
|
158
169
|
}
|
|
159
|
-
|
|
170
|
+
|
|
160
171
|
// when this is set, the callout's content will be whatever react views the user has put as the callout's
|
|
161
172
|
// children.
|
|
162
173
|
calloutView.contentView = self.calloutView;
|
|
163
|
-
|
|
174
|
+
|
|
164
175
|
} else {
|
|
165
|
-
|
|
176
|
+
|
|
166
177
|
// if there is no calloutView, it means the user wants to use the default callout behavior with title/subtitle
|
|
167
178
|
// pairs.
|
|
168
179
|
calloutView.title = self.title;
|
|
@@ -176,37 +187,37 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
176
187
|
{
|
|
177
188
|
_calloutIsOpen = YES;
|
|
178
189
|
[self setZIndex:_zIndexBeforeOpen];
|
|
179
|
-
|
|
190
|
+
|
|
180
191
|
MKAnnotationView *annotationView = [self getAnnotationView];
|
|
181
|
-
|
|
192
|
+
|
|
182
193
|
[self setSelected:YES animated:NO];
|
|
183
194
|
[self.map selectAnnotation:self animated:NO];
|
|
184
|
-
|
|
195
|
+
|
|
185
196
|
id event = @{
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
197
|
+
@"action": @"marker-select",
|
|
198
|
+
@"id": self.identifier ?: @"unknown",
|
|
199
|
+
@"coordinate": @{
|
|
200
|
+
@"latitude": @(self.coordinate.latitude),
|
|
201
|
+
@"longitude": @(self.coordinate.longitude)
|
|
202
|
+
}
|
|
192
203
|
};
|
|
193
|
-
|
|
204
|
+
|
|
194
205
|
if (self.map.onMarkerSelect) self.map.onMarkerSelect(event);
|
|
195
206
|
if (self.onSelect) self.onSelect(event);
|
|
196
|
-
|
|
207
|
+
|
|
197
208
|
if (![self shouldShowCalloutView]) {
|
|
198
209
|
// no callout to show
|
|
199
210
|
return;
|
|
200
211
|
}
|
|
201
|
-
|
|
212
|
+
|
|
202
213
|
[self fillCalloutView:self.map.calloutView];
|
|
203
|
-
|
|
214
|
+
|
|
204
215
|
// This is where we present our custom callout view... MapKit's built-in callout doesn't have the flexibility
|
|
205
216
|
// we need, but a lot of work was done by Nick Farina to make this identical to MapKit's built-in.
|
|
206
217
|
[self.map.calloutView presentCalloutFromRect:annotationView.bounds
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
218
|
+
inView:annotationView
|
|
219
|
+
constrainedToView:self.map
|
|
220
|
+
animated:YES];
|
|
210
221
|
}
|
|
211
222
|
|
|
212
223
|
#pragma mark - Tap Gesture & Events.
|
|
@@ -228,12 +239,12 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
228
239
|
- (void)_handleTap:(UITapGestureRecognizer *)recognizer {
|
|
229
240
|
AIRMapMarker *marker = self;
|
|
230
241
|
if (!marker) return;
|
|
231
|
-
|
|
242
|
+
|
|
232
243
|
if (marker.selected) {
|
|
233
244
|
CGPoint touchPoint = [recognizer locationInView:marker.map.calloutView];
|
|
234
245
|
CGRect bubbleFrame = [self.calloutView convertRect:marker.map.calloutView.bounds toView:marker.map];
|
|
235
246
|
CGPoint touchPointReal = [recognizer locationInView:self.calloutView];
|
|
236
|
-
|
|
247
|
+
|
|
237
248
|
UIView *calloutView = [marker.map.calloutView hitTest:touchPoint withEvent:nil];
|
|
238
249
|
if (calloutView) {
|
|
239
250
|
// the callout (or its subview) got clicked, not the marker
|
|
@@ -247,22 +258,22 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
247
258
|
}
|
|
248
259
|
tmp = tmp.superview;
|
|
249
260
|
}
|
|
250
|
-
|
|
261
|
+
|
|
251
262
|
id event = @{
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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
|
+
|
|
266
277
|
if (calloutSubview) calloutSubview.onPress(event);
|
|
267
278
|
if (marker.onCalloutPress) marker.onCalloutPress(event);
|
|
268
279
|
if (marker.calloutView && marker.calloutView.onPress) marker.calloutView.onPress(event);
|
|
@@ -270,25 +281,25 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
270
281
|
return;
|
|
271
282
|
}
|
|
272
283
|
}
|
|
273
|
-
|
|
284
|
+
|
|
274
285
|
// the actual marker got clicked
|
|
275
286
|
CGPoint touchPointReal = [recognizer locationInView:self.calloutView];
|
|
276
287
|
id event = @{
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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
|
+
|
|
289
300
|
if (marker.onPress) marker.onPress(event);
|
|
290
301
|
if (marker.map.onMarkerPress) marker.map.onMarkerPress(event);
|
|
291
|
-
|
|
302
|
+
|
|
292
303
|
[marker.map selectAnnotation:marker animated:NO];
|
|
293
304
|
}
|
|
294
305
|
|
|
@@ -298,19 +309,19 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
298
309
|
[self setZIndex:_zIndexBeforeOpen];
|
|
299
310
|
// hide the callout view
|
|
300
311
|
[self.map.calloutView dismissCalloutAnimated:YES];
|
|
301
|
-
|
|
312
|
+
|
|
302
313
|
[self setSelected:NO animated:NO];
|
|
303
314
|
[self.map deselectAnnotation:self animated:NO];
|
|
304
|
-
|
|
315
|
+
|
|
305
316
|
id event = @{
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
317
|
+
@"action": @"marker-deselect",
|
|
318
|
+
@"id": self.identifier ?: @"unknown",
|
|
319
|
+
@"coordinate": @{
|
|
320
|
+
@"latitude": @(self.coordinate.latitude),
|
|
321
|
+
@"longitude": @(self.coordinate.longitude)
|
|
322
|
+
}
|
|
312
323
|
};
|
|
313
|
-
|
|
324
|
+
|
|
314
325
|
if (self.map.onMarkerDeselect) self.map.onMarkerDeselect(event);
|
|
315
326
|
if (self.onDeselect) self.onDeselect(event);
|
|
316
327
|
}
|
|
@@ -333,39 +344,42 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
333
344
|
|
|
334
345
|
- (void)setOpacity:(double)opacity
|
|
335
346
|
{
|
|
336
|
-
|
|
347
|
+
[self setAlpha:opacity];
|
|
337
348
|
}
|
|
338
349
|
|
|
339
350
|
- (void)setImageSrc:(NSString *)imageSrc
|
|
340
351
|
{
|
|
341
352
|
_imageSrc = imageSrc;
|
|
342
|
-
|
|
353
|
+
|
|
343
354
|
if (_reloadImageCancellationBlock) {
|
|
344
355
|
_reloadImageCancellationBlock();
|
|
345
356
|
_reloadImageCancellationBlock = nil;
|
|
346
357
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
358
|
+
__weak __typeof(self) weakSelf = self;
|
|
359
|
+
|
|
360
|
+
_reloadImageCancellationBlock = [[[RCTBridge currentBridge] moduleForName:@"ImageLoader"] loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc]
|
|
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
|
+
}];
|
|
363
377
|
}
|
|
364
378
|
|
|
365
379
|
- (void)setPinColor:(UIColor *)pinColor
|
|
366
380
|
{
|
|
367
381
|
_pinColor = pinColor;
|
|
368
|
-
|
|
382
|
+
|
|
369
383
|
if(_useLegacyPinView && [_pinView respondsToSelector:@selector(setPinTintColor:)]) {
|
|
370
384
|
_pinView.pinTintColor = _pinColor;
|
|
371
385
|
} else {
|
|
@@ -381,7 +395,7 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
381
395
|
}
|
|
382
396
|
|
|
383
397
|
- (BOOL)isSelected {
|
|
384
|
-
|
|
398
|
+
return _isPreselected || [super isSelected];
|
|
385
399
|
}
|
|
386
400
|
|
|
387
401
|
- (void)dealloc {
|
|
@@ -398,4 +412,47 @@ NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999;
|
|
|
398
412
|
_useLegacyPinView = value;
|
|
399
413
|
}
|
|
400
414
|
|
|
415
|
+
- (void)animateToCoordinate:(CLLocationCoordinate2D)newCoordinate duration:(NSTimeInterval)duration {
|
|
416
|
+
if (_isAnimating) {
|
|
417
|
+
NSLog(@"Animation already in progress. Rejecting new animation request.");
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Mark as animating
|
|
422
|
+
_isAnimating = YES;
|
|
423
|
+
|
|
424
|
+
// Store animation parameters
|
|
425
|
+
_startCoordinate = self.coordinate;
|
|
426
|
+
_endCoordinate = newCoordinate;
|
|
427
|
+
_animationDuration = duration;
|
|
428
|
+
_animationStartTime = [NSDate timeIntervalSinceReferenceDate];
|
|
429
|
+
|
|
430
|
+
// Start a CADisplayLink
|
|
431
|
+
if (_displayLink) {
|
|
432
|
+
[_displayLink invalidate];
|
|
433
|
+
}
|
|
434
|
+
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updatePosition)];
|
|
435
|
+
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
- (void)updatePosition {
|
|
439
|
+
NSTimeInterval elapsed = [NSDate timeIntervalSinceReferenceDate] - _animationStartTime;
|
|
440
|
+
CGFloat progress = MIN(elapsed / _animationDuration, 1.0);
|
|
441
|
+
|
|
442
|
+
// Interpolate coordinates
|
|
443
|
+
CLLocationDegrees currentLatitude = _startCoordinate.latitude + progress * (_endCoordinate.latitude - _startCoordinate.latitude);
|
|
444
|
+
CLLocationDegrees currentLongitude = _startCoordinate.longitude + progress * (_endCoordinate.longitude - _startCoordinate.longitude);
|
|
445
|
+
|
|
446
|
+
// Update annotation's coordinate
|
|
447
|
+
CLLocationCoordinate2D currentCoordinate = CLLocationCoordinate2DMake(currentLatitude, currentLongitude);
|
|
448
|
+
[self setValue:[NSValue valueWithMKCoordinate:currentCoordinate] forKey:@"coordinate"];
|
|
449
|
+
|
|
450
|
+
// Stop the animation when complete
|
|
451
|
+
if (progress == 1.0) {
|
|
452
|
+
[_displayLink invalidate];
|
|
453
|
+
_displayLink = nil;
|
|
454
|
+
_isAnimating = NO; // Reset the animation state
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
401
458
|
@end
|
|
@@ -855,4 +855,4 @@ static UIImage *blackArrowImage = nil, *whiteArrowImage = nil, *grayArrowImage =
|
|
|
855
855
|
- (CGFloat)frameBottom { return self.frame.origin.y + self.frame.size.height; }
|
|
856
856
|
- (void)setFrameBottom:(CGFloat)bottom { self.frame = (CGRect){ .origin=self.frame.origin, .size.width=self.frame.size.width, .size.height=fmaxf(bottom-self.frame.origin.y,0) }; }
|
|
857
857
|
|
|
858
|
-
@end
|
|
858
|
+
@end
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
#import <MapKit/MapKit.h>
|
|
8
8
|
#import <React/RCTConvert.h>
|
|
9
9
|
|
|
10
|
+
@class AIRMapCoordinate;
|
|
11
|
+
|
|
10
12
|
@interface RCTConvert (AirMap)
|
|
11
13
|
|
|
12
14
|
+ (MKCoordinateSpan)MKCoordinateSpan:(id)json;
|
|
@@ -16,4 +18,6 @@
|
|
|
16
18
|
+ (MKMapType)MKMapType:(id)json;
|
|
17
19
|
+ (NSDictionary*) dictonaryFromString:(NSString *) str;
|
|
18
20
|
+ (NSArray*) arrayFromString:(NSString *) str;
|
|
21
|
+
+ (NSArray<NSArray<AIRMapCoordinate *> *> *)AIRMapCoordinateArrayArray:(id)json;
|
|
22
|
+
+ (AIRMapCoordinate*) AIRMapCoordinate:(id)json;
|
|
19
23
|
@end
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
|
|
30
31
|
+ (MKMapCamera*)MKMapCamera:(id)json
|
|
31
32
|
{
|
|
32
33
|
json = [self NSDictionary:json];
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
error:&jsonError];
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
|
|
52
54
|
+ (MKMapCamera*)MKMapCameraWithDefaults:(id)json existingCamera:(MKMapCamera*)camera
|
|
53
55
|
{
|
|
54
56
|
json = [self NSDictionary:json];
|