2015-03-23 20:28:42 +00:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*/
|
2015-03-10 01:05:10 +00:00
|
|
|
|
|
|
|
#import "RCTMapManager.h"
|
|
|
|
|
|
|
|
#import "RCTBridge.h"
|
2015-04-15 00:51:28 +00:00
|
|
|
#import "RCTConvert+CoreLocation.h"
|
|
|
|
#import "RCTConvert+MapKit.h"
|
2015-03-10 01:05:10 +00:00
|
|
|
#import "RCTEventDispatcher.h"
|
|
|
|
#import "RCTMap.h"
|
2015-11-26 11:04:33 +00:00
|
|
|
#import "RCTUtils.h"
|
2015-03-26 09:58:06 +00:00
|
|
|
#import "UIView+React.h"
|
Add Polyline support to MapView
Summary: Per issue #1925, add support for Polyline to MapView.
Briefly, if you have a MapView declared as:
<MapView
annotations={this.state.annotations}
overlays={this.state.overlays}
style={styles.map}
region={this.state.region}
ref="mapView"
/>
then setting
this.state.overlays = [{
coordinates: [
{ latitude: 35.5, longitude: -5.5 },
{ latitude: 35.6, longitude: -5.6 },
...
],
strokeColor: 'rgba(255, 0, 0, 0.5)',
lineWidth: 3,
}];
will draw a red line between the points in locations with a width of 3 and equally blended with the background.
Closes https://github.com/facebook/react-native/pull/4153
Reviewed By: svcscm
Differential Revision: D2697347
Pulled By: nicklockwood
fb-gh-sync-id: a436e4ed8d4e43f2872b39b4694fad7c02de8fe5
2015-11-26 15:09:59 +00:00
|
|
|
#import "RCTMapAnnotation.h"
|
|
|
|
#import "RCTMapOverlay.h"
|
2015-06-25 16:07:19 +00:00
|
|
|
|
|
|
|
#import <MapKit/MapKit.h>
|
2015-03-10 01:05:10 +00:00
|
|
|
|
2015-04-15 00:51:28 +00:00
|
|
|
static NSString *const RCTMapViewKey = @"MapView";
|
2015-03-26 04:29:28 +00:00
|
|
|
|
2015-03-10 01:05:10 +00:00
|
|
|
@interface RCTMapManager() <MKMapViewDelegate>
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation RCTMapManager
|
|
|
|
|
2015-04-08 12:42:43 +00:00
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
|
2015-03-10 01:05:10 +00:00
|
|
|
- (UIView *)view
|
|
|
|
{
|
2015-08-17 14:35:34 +00:00
|
|
|
RCTMap *map = [RCTMap new];
|
2015-03-10 01:05:10 +00:00
|
|
|
map.delegate = self;
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
2015-03-26 04:29:28 +00:00
|
|
|
RCT_EXPORT_VIEW_PROPERTY(showsUserLocation, BOOL)
|
2015-10-29 17:56:27 +00:00
|
|
|
RCT_EXPORT_VIEW_PROPERTY(showsPointsOfInterest, BOOL)
|
2015-11-19 10:20:23 +00:00
|
|
|
RCT_EXPORT_VIEW_PROPERTY(showsCompass, BOOL)
|
2015-03-26 04:29:28 +00:00
|
|
|
RCT_EXPORT_VIEW_PROPERTY(zoomEnabled, BOOL)
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(rotateEnabled, BOOL)
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(pitchEnabled, BOOL)
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(scrollEnabled, BOOL)
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(maxDelta, CGFloat)
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(minDelta, CGFloat)
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(legalLabelInsets, UIEdgeInsets)
|
2015-06-11 17:46:28 +00:00
|
|
|
RCT_EXPORT_VIEW_PROPERTY(mapType, MKMapType)
|
Add Polyline support to MapView
Summary: Per issue #1925, add support for Polyline to MapView.
Briefly, if you have a MapView declared as:
<MapView
annotations={this.state.annotations}
overlays={this.state.overlays}
style={styles.map}
region={this.state.region}
ref="mapView"
/>
then setting
this.state.overlays = [{
coordinates: [
{ latitude: 35.5, longitude: -5.5 },
{ latitude: 35.6, longitude: -5.6 },
...
],
strokeColor: 'rgba(255, 0, 0, 0.5)',
lineWidth: 3,
}];
will draw a red line between the points in locations with a width of 3 and equally blended with the background.
Closes https://github.com/facebook/react-native/pull/4153
Reviewed By: svcscm
Differential Revision: D2697347
Pulled By: nicklockwood
fb-gh-sync-id: a436e4ed8d4e43f2872b39b4694fad7c02de8fe5
2015-11-26 15:09:59 +00:00
|
|
|
RCT_EXPORT_VIEW_PROPERTY(annotations, RCTMapAnnotationArray)
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(overlays, RCTMapOverlayArray)
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock)
|
2015-04-16 12:29:06 +00:00
|
|
|
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
|
|
|
{
|
|
|
|
[view setRegion:json ? [RCTConvert MKCoordinateRegion:json] : defaultView.region animated:YES];
|
|
|
|
}
|
2015-03-10 01:05:10 +00:00
|
|
|
|
2015-11-26 11:04:33 +00:00
|
|
|
- (NSDictionary<NSString *, id> *)constantsToExport
|
|
|
|
{
|
|
|
|
return @{
|
|
|
|
@"PinColors": @{
|
|
|
|
@"RED": RCTColorToHexString([MKPinAnnotationView redPinColor].CGColor),
|
|
|
|
@"GREEN": RCTColorToHexString([MKPinAnnotationView greenPinColor].CGColor),
|
|
|
|
@"PURPLE": RCTColorToHexString([MKPinAnnotationView purplePinColor].CGColor),
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2015-03-10 01:05:10 +00:00
|
|
|
#pragma mark MKMapViewDelegate
|
|
|
|
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
- (void)mapView:(RCTMap *)mapView didSelectAnnotationView:(MKAnnotationView *)view
|
2015-06-25 16:07:19 +00:00
|
|
|
{
|
Add Polyline support to MapView
Summary: Per issue #1925, add support for Polyline to MapView.
Briefly, if you have a MapView declared as:
<MapView
annotations={this.state.annotations}
overlays={this.state.overlays}
style={styles.map}
region={this.state.region}
ref="mapView"
/>
then setting
this.state.overlays = [{
coordinates: [
{ latitude: 35.5, longitude: -5.5 },
{ latitude: 35.6, longitude: -5.6 },
...
],
strokeColor: 'rgba(255, 0, 0, 0.5)',
lineWidth: 3,
}];
will draw a red line between the points in locations with a width of 3 and equally blended with the background.
Closes https://github.com/facebook/react-native/pull/4153
Reviewed By: svcscm
Differential Revision: D2697347
Pulled By: nicklockwood
fb-gh-sync-id: a436e4ed8d4e43f2872b39b4694fad7c02de8fe5
2015-11-26 15:09:59 +00:00
|
|
|
if (mapView.onPress && [view.annotation isKindOfClass:[RCTMapAnnotation class]]) {
|
2015-06-25 16:07:19 +00:00
|
|
|
|
Add Polyline support to MapView
Summary: Per issue #1925, add support for Polyline to MapView.
Briefly, if you have a MapView declared as:
<MapView
annotations={this.state.annotations}
overlays={this.state.overlays}
style={styles.map}
region={this.state.region}
ref="mapView"
/>
then setting
this.state.overlays = [{
coordinates: [
{ latitude: 35.5, longitude: -5.5 },
{ latitude: 35.6, longitude: -5.6 },
...
],
strokeColor: 'rgba(255, 0, 0, 0.5)',
lineWidth: 3,
}];
will draw a red line between the points in locations with a width of 3 and equally blended with the background.
Closes https://github.com/facebook/react-native/pull/4153
Reviewed By: svcscm
Differential Revision: D2697347
Pulled By: nicklockwood
fb-gh-sync-id: a436e4ed8d4e43f2872b39b4694fad7c02de8fe5
2015-11-26 15:09:59 +00:00
|
|
|
RCTMapAnnotation *annotation = (RCTMapAnnotation *)view.annotation;
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
mapView.onPress(@{
|
|
|
|
@"action": @"annotation-click",
|
|
|
|
@"annotation": @{
|
|
|
|
@"id": annotation.identifier,
|
|
|
|
@"title": annotation.title ?: @"",
|
|
|
|
@"subtitle": annotation.subtitle ?: @"",
|
|
|
|
@"latitude": @(annotation.coordinate.latitude),
|
|
|
|
@"longitude": @(annotation.coordinate.longitude)
|
|
|
|
}
|
|
|
|
});
|
2015-06-25 16:07:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add Polyline support to MapView
Summary: Per issue #1925, add support for Polyline to MapView.
Briefly, if you have a MapView declared as:
<MapView
annotations={this.state.annotations}
overlays={this.state.overlays}
style={styles.map}
region={this.state.region}
ref="mapView"
/>
then setting
this.state.overlays = [{
coordinates: [
{ latitude: 35.5, longitude: -5.5 },
{ latitude: 35.6, longitude: -5.6 },
...
],
strokeColor: 'rgba(255, 0, 0, 0.5)',
lineWidth: 3,
}];
will draw a red line between the points in locations with a width of 3 and equally blended with the background.
Closes https://github.com/facebook/react-native/pull/4153
Reviewed By: svcscm
Differential Revision: D2697347
Pulled By: nicklockwood
fb-gh-sync-id: a436e4ed8d4e43f2872b39b4694fad7c02de8fe5
2015-11-26 15:09:59 +00:00
|
|
|
- (MKAnnotationView *)mapView:(__unused MKMapView *)mapView viewForAnnotation:(RCTMapAnnotation *)annotation
|
2015-06-25 16:07:19 +00:00
|
|
|
{
|
Add Polyline support to MapView
Summary: Per issue #1925, add support for Polyline to MapView.
Briefly, if you have a MapView declared as:
<MapView
annotations={this.state.annotations}
overlays={this.state.overlays}
style={styles.map}
region={this.state.region}
ref="mapView"
/>
then setting
this.state.overlays = [{
coordinates: [
{ latitude: 35.5, longitude: -5.5 },
{ latitude: 35.6, longitude: -5.6 },
...
],
strokeColor: 'rgba(255, 0, 0, 0.5)',
lineWidth: 3,
}];
will draw a red line between the points in locations with a width of 3 and equally blended with the background.
Closes https://github.com/facebook/react-native/pull/4153
Reviewed By: svcscm
Differential Revision: D2697347
Pulled By: nicklockwood
fb-gh-sync-id: a436e4ed8d4e43f2872b39b4694fad7c02de8fe5
2015-11-26 15:09:59 +00:00
|
|
|
if (![annotation isKindOfClass:[RCTMapAnnotation class]]) {
|
2015-06-25 16:07:19 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2015-11-26 11:04:33 +00:00
|
|
|
MKAnnotationView *annotationView;
|
|
|
|
if (annotation.image) {
|
|
|
|
if (annotation.tintColor) {
|
|
|
|
|
|
|
|
NSString *const reuseIdentifier = @"RCTImageViewAnnotation";
|
|
|
|
NSInteger imageViewTag = 99;
|
|
|
|
annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier];
|
|
|
|
if (!annotationView) {
|
|
|
|
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
|
|
|
|
UIImageView *imageView = [UIImageView new];
|
|
|
|
imageView.tag = imageViewTag;
|
|
|
|
[annotationView addSubview:imageView];
|
|
|
|
}
|
|
|
|
|
|
|
|
UIImageView *imageView = (UIImageView *)[annotationView viewWithTag:imageViewTag];
|
|
|
|
imageView.image = annotation.image;
|
|
|
|
imageView.tintColor = annotation.tintColor;
|
|
|
|
[imageView sizeToFit];
|
|
|
|
imageView.center = CGPointZero;
|
|
|
|
|
|
|
|
} else {
|
2015-06-25 16:07:19 +00:00
|
|
|
|
2015-11-26 11:04:33 +00:00
|
|
|
NSString *reuseIdentifier = NSStringFromClass([MKAnnotationView class]);
|
|
|
|
annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier] ?: [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
|
|
|
|
annotationView.image = annotation.image;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
NSString *reuseIdentifier = NSStringFromClass([MKPinAnnotationView class]);
|
|
|
|
annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier] ?: [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
|
|
|
|
((MKPinAnnotationView *)annotationView).animatesDrop = annotation.animateDrop;
|
|
|
|
((MKPinAnnotationView *)annotationView).pinTintColor = annotation.tintColor ?: [MKPinAnnotationView redPinColor];
|
|
|
|
}
|
2015-06-25 16:07:19 +00:00
|
|
|
annotationView.canShowCallout = true;
|
|
|
|
|
|
|
|
annotationView.leftCalloutAccessoryView = nil;
|
|
|
|
if (annotation.hasLeftCallout) {
|
|
|
|
annotationView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
|
|
|
|
}
|
|
|
|
|
|
|
|
annotationView.rightCalloutAccessoryView = nil;
|
|
|
|
if (annotation.hasRightCallout) {
|
|
|
|
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
|
|
|
|
}
|
|
|
|
|
|
|
|
return annotationView;
|
|
|
|
}
|
|
|
|
|
Add Polyline support to MapView
Summary: Per issue #1925, add support for Polyline to MapView.
Briefly, if you have a MapView declared as:
<MapView
annotations={this.state.annotations}
overlays={this.state.overlays}
style={styles.map}
region={this.state.region}
ref="mapView"
/>
then setting
this.state.overlays = [{
coordinates: [
{ latitude: 35.5, longitude: -5.5 },
{ latitude: 35.6, longitude: -5.6 },
...
],
strokeColor: 'rgba(255, 0, 0, 0.5)',
lineWidth: 3,
}];
will draw a red line between the points in locations with a width of 3 and equally blended with the background.
Closes https://github.com/facebook/react-native/pull/4153
Reviewed By: svcscm
Differential Revision: D2697347
Pulled By: nicklockwood
fb-gh-sync-id: a436e4ed8d4e43f2872b39b4694fad7c02de8fe5
2015-11-26 15:09:59 +00:00
|
|
|
- (MKOverlayRenderer *)mapView:(__unused MKMapView *)mapView rendererForOverlay:(RCTMapOverlay *)overlay
|
|
|
|
{
|
|
|
|
if ([overlay isKindOfClass:[RCTMapOverlay class]]) {
|
|
|
|
MKPolylineRenderer *polylineRenderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
|
|
|
|
polylineRenderer.strokeColor = overlay.strokeColor;
|
|
|
|
polylineRenderer.lineWidth = overlay.lineWidth;
|
|
|
|
return polylineRenderer;
|
|
|
|
} else {
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
- (void)mapView:(RCTMap *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
|
2015-06-25 16:07:19 +00:00
|
|
|
{
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
if (mapView.onPress) {
|
2015-06-25 16:07:19 +00:00
|
|
|
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
// Pass to js
|
Add Polyline support to MapView
Summary: Per issue #1925, add support for Polyline to MapView.
Briefly, if you have a MapView declared as:
<MapView
annotations={this.state.annotations}
overlays={this.state.overlays}
style={styles.map}
region={this.state.region}
ref="mapView"
/>
then setting
this.state.overlays = [{
coordinates: [
{ latitude: 35.5, longitude: -5.5 },
{ latitude: 35.6, longitude: -5.6 },
...
],
strokeColor: 'rgba(255, 0, 0, 0.5)',
lineWidth: 3,
}];
will draw a red line between the points in locations with a width of 3 and equally blended with the background.
Closes https://github.com/facebook/react-native/pull/4153
Reviewed By: svcscm
Differential Revision: D2697347
Pulled By: nicklockwood
fb-gh-sync-id: a436e4ed8d4e43f2872b39b4694fad7c02de8fe5
2015-11-26 15:09:59 +00:00
|
|
|
RCTMapAnnotation *annotation = (RCTMapAnnotation *)view.annotation;
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
mapView.onPress(@{
|
|
|
|
@"side": (control == view.leftCalloutAccessoryView) ? @"left" : @"right",
|
2015-06-25 16:07:19 +00:00
|
|
|
@"action": @"callout-click",
|
|
|
|
@"annotationId": annotation.identifier
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
});
|
|
|
|
}
|
2015-06-25 16:07:19 +00:00
|
|
|
}
|
|
|
|
|
2015-03-10 01:05:10 +00:00
|
|
|
- (void)mapView:(RCTMap *)mapView didUpdateUserLocation:(MKUserLocation *)location
|
|
|
|
{
|
|
|
|
if (mapView.followUserLocation) {
|
|
|
|
MKCoordinateRegion region;
|
|
|
|
region.span.latitudeDelta = RCTMapDefaultSpan;
|
|
|
|
region.span.longitudeDelta = RCTMapDefaultSpan;
|
|
|
|
region.center = location.coordinate;
|
|
|
|
[mapView setRegion:region animated:YES];
|
|
|
|
|
|
|
|
// Move to user location only for the first time it loads up.
|
|
|
|
mapView.followUserLocation = NO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-15 14:53:45 +00:00
|
|
|
- (void)mapView:(RCTMap *)mapView regionWillChangeAnimated:(__unused BOOL)animated
|
2015-03-10 01:05:10 +00:00
|
|
|
{
|
|
|
|
[self _regionChanged:mapView];
|
|
|
|
|
2015-04-21 17:19:18 +00:00
|
|
|
mapView.regionChangeObserveTimer = [NSTimer timerWithTimeInterval:RCTMapRegionChangeObserveInterval
|
|
|
|
target:self
|
|
|
|
selector:@selector(_onTick:)
|
|
|
|
userInfo:@{ RCTMapViewKey: mapView }
|
|
|
|
repeats:YES];
|
|
|
|
|
|
|
|
[[NSRunLoop mainRunLoop] addTimer:mapView.regionChangeObserveTimer forMode:NSRunLoopCommonModes];
|
2015-03-10 01:05:10 +00:00
|
|
|
}
|
|
|
|
|
2015-06-15 14:53:45 +00:00
|
|
|
- (void)mapView:(RCTMap *)mapView regionDidChangeAnimated:(__unused BOOL)animated
|
2015-03-10 01:05:10 +00:00
|
|
|
{
|
|
|
|
[mapView.regionChangeObserveTimer invalidate];
|
|
|
|
mapView.regionChangeObserveTimer = nil;
|
2015-03-13 16:10:57 +00:00
|
|
|
|
|
|
|
[self _regionChanged:mapView];
|
2015-04-15 00:51:28 +00:00
|
|
|
|
|
|
|
// Don't send region did change events until map has
|
2015-05-07 23:20:08 +00:00
|
|
|
// started rendering, as these won't represent the final location
|
|
|
|
if (mapView.hasStartedRendering) {
|
2015-04-15 00:51:28 +00:00
|
|
|
[self _emitRegionChangeEvent:mapView continuous:NO];
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2015-05-07 23:20:08 +00:00
|
|
|
- (void)mapViewWillStartRenderingMap:(RCTMap *)mapView
|
2015-04-15 00:51:28 +00:00
|
|
|
{
|
2015-05-07 23:20:08 +00:00
|
|
|
mapView.hasStartedRendering = YES;
|
2015-03-13 16:10:57 +00:00
|
|
|
[self _emitRegionChangeEvent:mapView continuous:NO];
|
2015-03-10 01:05:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark Private
|
|
|
|
|
|
|
|
- (void)_onTick:(NSTimer *)timer
|
|
|
|
{
|
2015-04-15 00:51:28 +00:00
|
|
|
[self _regionChanged:timer.userInfo[RCTMapViewKey]];
|
2015-03-10 01:05:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_regionChanged:(RCTMap *)mapView
|
|
|
|
{
|
|
|
|
BOOL needZoom = NO;
|
|
|
|
CGFloat newLongitudeDelta = 0.0f;
|
|
|
|
MKCoordinateRegion region = mapView.region;
|
2015-11-26 11:04:33 +00:00
|
|
|
|
|
|
|
// On iOS 7, it's possible that we observe invalid locations during
|
|
|
|
// initialization of the map. Filter those out.
|
2015-03-10 01:05:10 +00:00
|
|
|
if (!CLLocationCoordinate2DIsValid(region.center)) {
|
|
|
|
return;
|
|
|
|
}
|
2015-11-26 11:04:33 +00:00
|
|
|
|
|
|
|
// Calculation on float is not 100% accurate. If user zoom to max/min and then
|
|
|
|
// move, it's likely the map will auto zoom to max/min from time to time.
|
|
|
|
// So let's try to make map zoom back to 99% max or 101% min so that there is
|
|
|
|
// some buffer, and moving the map won't constantly hit the max/min bound.
|
2015-03-10 01:05:10 +00:00
|
|
|
if (mapView.maxDelta > FLT_EPSILON && region.span.longitudeDelta > mapView.maxDelta) {
|
|
|
|
needZoom = YES;
|
|
|
|
newLongitudeDelta = mapView.maxDelta * (1 - RCTMapZoomBoundBuffer);
|
|
|
|
} else if (mapView.minDelta > FLT_EPSILON && region.span.longitudeDelta < mapView.minDelta) {
|
|
|
|
needZoom = YES;
|
|
|
|
newLongitudeDelta = mapView.minDelta * (1 + RCTMapZoomBoundBuffer);
|
|
|
|
}
|
|
|
|
if (needZoom) {
|
|
|
|
region.span.latitudeDelta = region.span.latitudeDelta / region.span.longitudeDelta * newLongitudeDelta;
|
|
|
|
region.span.longitudeDelta = newLongitudeDelta;
|
|
|
|
mapView.region = region;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Continously observe region changes
|
|
|
|
[self _emitRegionChangeEvent:mapView continuous:YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_emitRegionChangeEvent:(RCTMap *)mapView continuous:(BOOL)continuous
|
|
|
|
{
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
if (mapView.onChange) {
|
|
|
|
MKCoordinateRegion region = mapView.region;
|
|
|
|
if (!CLLocationCoordinate2DIsValid(region.center)) {
|
|
|
|
return;
|
2015-03-26 04:29:28 +00:00
|
|
|
}
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
|
|
|
|
mapView.onChange(@{
|
|
|
|
@"continuous": @(continuous),
|
|
|
|
@"region": @{
|
2015-11-26 11:04:33 +00:00
|
|
|
@"latitude": @(RCTZeroIfNaN(region.center.latitude)),
|
|
|
|
@"longitude": @(RCTZeroIfNaN(region.center.longitude)),
|
|
|
|
@"latitudeDelta": @(RCTZeroIfNaN(region.span.latitudeDelta)),
|
|
|
|
@"longitudeDelta": @(RCTZeroIfNaN(region.span.longitudeDelta)),
|
Added mechanism for directly mapping JS event handlers to blocks
Summary:
Currently, the system for mapping JS event handlers to blocks is quite clean on the JS side, but is clunky on the native side. The event property is passed as a boolean, which can then be checked by the native side, and if true, the native side is supposed to send an event via the event dispatcher.
This diff adds the facility to declare the property as a block instead. This means that the event side can simply call the block, and it will automatically send the event. Because the blocks for bubbling and direct events are named differently, we can also use this to generate the event registration data and get rid of the arrays of event names.
The name of the event is inferred from the property name, which means that the property for an event called "load" must be called `onLoad` or the mapping won't work. This can be optionally remapped to a different property name on the view itself if necessary, e.g.
RCT_REMAP_VIEW_PROPERTY(onLoad, loadEventBlock, RCTDirectEventBlock)
If you don't want to use this mechanism then for now it is still possible to declare the property as a BOOL instead and use the old mechanism (this approach is now deprecated however, and may eventually be removed altogether).
2015-09-02 12:58:10 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2015-03-10 01:05:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|