[MapView] Support for annotation callouts, annotation press, callout presses and pin animation
Summary: Started from here - https://github.com/facebook/react-native/issues/1120. Most functionality for annotations were missing so I started implementing and somehow got caught up until the entire thing was done. ![screen shot 2015-05-12 at 10 07 43 pm](https://cloud.githubusercontent.com/assets/688326/7588677/8479a7a4-f8f9-11e4-99a4-1dc3c7691810.png) 2 new events: - callout presses (left / right) - annotation presses 6 new properties for annotations: - hasLeftCallout - hasRightCallout - onLeftCalloutPress - onRightCalloutPress - animateDrop - id 1 new property for MapView - onAnnotationPress --- Now the important thing is, that I implemented all of this the way "I would do it". I am not sure this is the 'reacty' way so please let me know my mistakes 😄 The problem is that there is no real way to identify annotations which makes it difficult to distinguish which one got clicked. The idea is to pass a `id` and whether it has callouts the entire way with the annotation. I had to Closes https://github.com/facebook/react-native/pull/1247 Github Author: David Mohl <me@dave.cx> Test Plan: Imported from GitHub, without a `Test Plan:` line.
This commit is contained in:
parent
3c5b4b0a9f
commit
99bc08cf61
|
@ -35,6 +35,34 @@ type MapRegion = {
|
|||
var MapView = React.createClass({
|
||||
mixins: [NativeMethodsMixin],
|
||||
|
||||
checkAnnotationIds: function (annotations: Array<Object>) {
|
||||
|
||||
var newAnnotations = annotations.map(function (annotation) {
|
||||
if (!annotation.id) {
|
||||
// TODO: add a base64 (or similar) encoder here
|
||||
annotation.id = encodeURIComponent(JSON.stringify(annotation));
|
||||
}
|
||||
|
||||
return annotation;
|
||||
});
|
||||
|
||||
this.setState({
|
||||
annotations: newAnnotations
|
||||
});
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
if (this.props.annotations) {
|
||||
this.checkAnnotationIds(this.props.annotations);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(nextProps: Object) {
|
||||
if (nextProps.annotations) {
|
||||
this.checkAnnotationIds(nextProps.annotations);
|
||||
}
|
||||
},
|
||||
|
||||
propTypes: {
|
||||
/**
|
||||
* Used to style and layout the `MapView`. See `StyleSheet.js` and
|
||||
|
@ -84,14 +112,14 @@ var MapView = React.createClass({
|
|||
|
||||
/**
|
||||
* The map type to be displayed.
|
||||
*
|
||||
*
|
||||
* - standard: standard road map (default)
|
||||
* - satellite: satellite view
|
||||
* - hybrid: satellite view with roads and points of interest overlayed
|
||||
*/
|
||||
mapType: React.PropTypes.oneOf([
|
||||
'standard',
|
||||
'satellite',
|
||||
'standard',
|
||||
'satellite',
|
||||
'hybrid',
|
||||
]),
|
||||
|
||||
|
@ -126,11 +154,34 @@ var MapView = React.createClass({
|
|||
latitude: React.PropTypes.number.isRequired,
|
||||
longitude: React.PropTypes.number.isRequired,
|
||||
|
||||
/**
|
||||
* Whether the pin drop should be animated or not
|
||||
*/
|
||||
animateDrop: React.PropTypes.bool,
|
||||
|
||||
/**
|
||||
* Annotation title/subtile.
|
||||
*/
|
||||
title: React.PropTypes.string,
|
||||
subtitle: React.PropTypes.string,
|
||||
|
||||
/**
|
||||
* Whether the Annotation has callout buttons.
|
||||
*/
|
||||
hasLeftCallout: React.PropTypes.bool,
|
||||
hasRightCallout: React.PropTypes.bool,
|
||||
|
||||
/**
|
||||
* Event handlers for callout buttons.
|
||||
*/
|
||||
onLeftCalloutPress: React.PropTypes.func,
|
||||
onRightCalloutPress: React.PropTypes.func,
|
||||
|
||||
/**
|
||||
* annotation id
|
||||
*/
|
||||
id: React.PropTypes.string
|
||||
|
||||
})),
|
||||
|
||||
/**
|
||||
|
@ -158,6 +209,11 @@ var MapView = React.createClass({
|
|||
* Callback that is called once, when the user is done moving the map.
|
||||
*/
|
||||
onRegionChangeComplete: React.PropTypes.func,
|
||||
|
||||
/**
|
||||
* Callback that is called once, when the user is clicked on a annotation.
|
||||
*/
|
||||
onAnnotationPress: React.PropTypes.func,
|
||||
},
|
||||
|
||||
_onChange: function(event: Event) {
|
||||
|
@ -170,8 +226,34 @@ var MapView = React.createClass({
|
|||
}
|
||||
},
|
||||
|
||||
_onPress: function(event: Event) {
|
||||
if (event.nativeEvent.action === 'annotation-click') {
|
||||
this.props.onAnnotationPress && this.props.onAnnotationPress(event.nativeEvent.annotation);
|
||||
}
|
||||
|
||||
if (event.nativeEvent.action === 'callout-click') {
|
||||
if (!this.props.annotations) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the annotation with the id of what has been pressed
|
||||
for (var i = 0; i < this.props.annotations.length; i++) {
|
||||
var annotation = this.props.annotations[i];
|
||||
if (annotation.id === event.nativeEvent.annotationId) {
|
||||
// Pass the right function
|
||||
if (event.nativeEvent.side === 'left') {
|
||||
annotation.onLeftCalloutPress && annotation.onLeftCalloutPress(event.nativeEvent);
|
||||
} else if (event.nativeEvent.side === 'right') {
|
||||
annotation.onRightCalloutPress && annotation.onRightCalloutPress(event.nativeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return <RCTMap {...this.props} onChange={this._onChange} />;
|
||||
return <RCTMap {...this.props} onPress={this._onPress} onChange={this._onChange} />;
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <MapKit/MapKit.h>
|
||||
|
||||
@interface RCTPointAnnotation : MKPointAnnotation <MKAnnotation>
|
||||
|
||||
@property (nonatomic, copy) NSString *identifier;
|
||||
@property (nonatomic, assign) BOOL hasLeftCallout;
|
||||
@property (nonatomic, assign) BOOL hasRightCallout;
|
||||
@property (nonatomic, assign) BOOL animateDrop;
|
||||
|
||||
@end
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTPointAnnotation.h"
|
||||
|
||||
@implementation RCTPointAnnotation
|
||||
|
||||
@end
|
|
@ -64,6 +64,7 @@
|
|||
58114A171AAE854800E7D092 /* RCTPickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A151AAE854800E7D092 /* RCTPickerManager.m */; };
|
||||
58114A501AAE93D500E7D092 /* RCTAsyncLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */; };
|
||||
58C571C11AA56C1900CDF9C8 /* RCTDatePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */; };
|
||||
63F014C01B02080B003B75D2 /* RCTPointAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F014BF1B02080B003B75D2 /* RCTPointAnnotation.m */; };
|
||||
830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; };
|
||||
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 830BA4541A8E3BDA00D53203 /* RCTCache.m */; };
|
||||
832348161A77A5AA00B55238 /* Layout.c in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FC71A68125100A75B9A /* Layout.c */; };
|
||||
|
@ -213,6 +214,8 @@
|
|||
58114A4F1AAE93D500E7D092 /* RCTAsyncLocalStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAsyncLocalStorage.h; sourceTree = "<group>"; };
|
||||
58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDatePickerManager.m; sourceTree = "<group>"; };
|
||||
58C571C01AA56C1900CDF9C8 /* RCTDatePickerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDatePickerManager.h; sourceTree = "<group>"; };
|
||||
63F014BE1B02080B003B75D2 /* RCTPointAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPointAnnotation.h; sourceTree = "<group>"; };
|
||||
63F014BF1B02080B003B75D2 /* RCTPointAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTPointAnnotation.m; sourceTree = "<group>"; };
|
||||
830213F31A654E0800B993E6 /* RCTBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = "<group>"; };
|
||||
830A229C1A66C68A008503DA /* RCTRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = "<group>"; };
|
||||
830A229D1A66C68A008503DA /* RCTRootView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = "<group>"; };
|
||||
|
@ -291,6 +294,8 @@
|
|||
13B07FEE1A69327A00A75B9A /* RCTTiming.m */,
|
||||
13E067481A70F434002CDEE1 /* RCTUIManager.h */,
|
||||
13E067491A70F434002CDEE1 /* RCTUIManager.m */,
|
||||
63F014BE1B02080B003B75D2 /* RCTPointAnnotation.h */,
|
||||
63F014BF1B02080B003B75D2 /* RCTPointAnnotation.m */,
|
||||
);
|
||||
path = Modules;
|
||||
sourceTree = "<group>";
|
||||
|
@ -599,6 +604,7 @@
|
|||
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */,
|
||||
137327E71AA5CF210034F82E /* RCTTabBar.m in Sources */,
|
||||
00C1A2B31AC0B7E000E89A1C /* RCTDevMenu.m in Sources */,
|
||||
63F014C01B02080B003B75D2 /* RCTPointAnnotation.m in Sources */,
|
||||
14435CE51AAC4AE100FC20F4 /* RCTMap.m in Sources */,
|
||||
134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */,
|
||||
13B0801C1A69489C00A75B9A /* RCTNavItem.m in Sources */,
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
//
|
||||
// RCTConvert+CoreLocation.h
|
||||
// React
|
||||
//
|
||||
// Created by Nick Lockwood on 12/04/2015.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
//
|
||||
// RCTConvert+CoreLocation.m
|
||||
// React
|
||||
//
|
||||
// Created by Nick Lockwood on 12/04/2015.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTConvert+CoreLocation.h"
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
//
|
||||
// RCTConvert+MapKit.h
|
||||
// React
|
||||
//
|
||||
// Created by Nick Lockwood on 12/04/2015.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <MapKit/MapKit.h>
|
||||
|
||||
#import "RCTPointAnnotation.h"
|
||||
#import "RCTConvert.h"
|
||||
|
||||
@interface RCTConvert (MapKit)
|
||||
|
@ -16,8 +18,12 @@
|
|||
+ (MKCoordinateRegion)MKCoordinateRegion:(id)json;
|
||||
+ (MKShape *)MKShape:(id)json;
|
||||
+ (MKMapType)MKMapType:(id)json;
|
||||
+ (RCTPointAnnotation *)RCTPointAnnotation:(id)json;
|
||||
|
||||
typedef NSArray MKShapeArray;
|
||||
+ (MKShapeArray *)MKShapeArray:(id)json;
|
||||
|
||||
typedef NSArray RCTPointAnnotationArray;
|
||||
+ (RCTPointAnnotationArray *)RCTPointAnnotationArray:(id)json;
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
//
|
||||
// RCTConvert+MapKit.m
|
||||
// React
|
||||
//
|
||||
// Created by Nick Lockwood on 12/04/2015.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTConvert+MapKit.h"
|
||||
|
||||
#import "RCTConvert+CoreLocation.h"
|
||||
#import "RCTPointAnnotation.h"
|
||||
|
||||
@implementation RCTConvert(MapKit)
|
||||
|
||||
|
@ -49,4 +50,20 @@ RCT_ENUM_CONVERTER(MKMapType, (@{
|
|||
@"hybrid": @(MKMapTypeHybrid),
|
||||
}), MKMapTypeStandard, integerValue)
|
||||
|
||||
+ (RCTPointAnnotation *)RCTPointAnnotation:(id)json
|
||||
{
|
||||
json = [self NSDictionary:json];
|
||||
RCTPointAnnotation *shape = [[RCTPointAnnotation alloc] init];
|
||||
shape.coordinate = [self CLLocationCoordinate2D:json];
|
||||
shape.title = [RCTConvert NSString:json[@"title"]];
|
||||
shape.subtitle = [RCTConvert NSString:json[@"subtitle"]];
|
||||
shape.identifier = [RCTConvert NSString:json[@"id"]];
|
||||
shape.hasLeftCallout = [RCTConvert BOOL:json[@"hasLeftCallout"]];
|
||||
shape.hasRightCallout = [RCTConvert BOOL:json[@"hasRightCallout"]];
|
||||
shape.animateDrop = [RCTConvert BOOL:json[@"animateDrop"]];
|
||||
return shape;
|
||||
}
|
||||
|
||||
RCT_ARRAY_CONVERTER(RCTPointAnnotation)
|
||||
|
||||
@end
|
||||
|
|
|
@ -26,7 +26,8 @@ extern const CGFloat RCTMapZoomBoundBuffer;
|
|||
@property (nonatomic, assign) CGFloat maxDelta;
|
||||
@property (nonatomic, assign) UIEdgeInsets legalLabelInsets;
|
||||
@property (nonatomic, strong) NSTimer *regionChangeObserveTimer;
|
||||
@property (nonatomic, strong) NSMutableArray *annotationIds;
|
||||
|
||||
- (void)setAnnotations:(MKShapeArray *)annotations;
|
||||
- (void)setAnnotations:(RCTPointAnnotationArray *)annotations;
|
||||
|
||||
@end
|
||||
|
|
|
@ -112,12 +112,52 @@ const CGFloat RCTMapZoomBoundBuffer = 0.01;
|
|||
[super setRegion:region animated:animated];
|
||||
}
|
||||
|
||||
- (void)setAnnotations:(MKShapeArray *)annotations
|
||||
- (void)setAnnotations:(RCTPointAnnotationArray *)annotations
|
||||
{
|
||||
[self removeAnnotations:self.annotations];
|
||||
if (annotations.count) {
|
||||
[self addAnnotations:annotations];
|
||||
NSMutableArray *newAnnotationIds = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *annotationsToDelete = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *annotationsToAdd = [[NSMutableArray alloc] init];
|
||||
|
||||
for (RCTPointAnnotation *annotation in annotations) {
|
||||
if (![annotation isKindOfClass:[RCTPointAnnotation class]]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
[newAnnotationIds addObject:annotation.identifier];
|
||||
|
||||
// If the current set does not contain the new annotation, mark it as add
|
||||
if (![self.annotationIds containsObject:annotation.identifier]) {
|
||||
[annotationsToAdd addObject:annotation];
|
||||
}
|
||||
}
|
||||
|
||||
for (RCTPointAnnotation *annotation in self.annotations) {
|
||||
if (![annotation isKindOfClass:[RCTPointAnnotation class]]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the new set does not contain an existing annotation, mark it as delete
|
||||
if (![newAnnotationIds containsObject:annotation.identifier]) {
|
||||
[annotationsToDelete addObject:annotation];
|
||||
}
|
||||
}
|
||||
|
||||
if (annotationsToDelete.count) {
|
||||
[self removeAnnotations:annotationsToDelete];
|
||||
}
|
||||
|
||||
if (annotationsToAdd.count) {
|
||||
[self addAnnotations:annotationsToAdd];
|
||||
}
|
||||
|
||||
NSMutableArray *newIds = [[NSMutableArray alloc] init];
|
||||
for (RCTPointAnnotation *anno in self.annotations) {
|
||||
if ([anno isKindOfClass:[MKUserLocation class]]) {
|
||||
continue;
|
||||
}
|
||||
[newIds addObject:anno.identifier];
|
||||
}
|
||||
self.annotationIds = newIds;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTMap.h"
|
||||
#import "UIView+React.h"
|
||||
#import "RCTPointAnnotation.h"
|
||||
|
||||
#import <MapKit/MapKit.h>
|
||||
|
||||
static NSString *const RCTMapViewKey = @"MapView";
|
||||
|
||||
|
@ -42,7 +45,7 @@ RCT_EXPORT_VIEW_PROPERTY(maxDelta, CGFloat)
|
|||
RCT_EXPORT_VIEW_PROPERTY(minDelta, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(legalLabelInsets, UIEdgeInsets)
|
||||
RCT_EXPORT_VIEW_PROPERTY(mapType, MKMapType)
|
||||
RCT_EXPORT_VIEW_PROPERTY(annotations, MKShapeArray)
|
||||
RCT_EXPORT_VIEW_PROPERTY(annotations, RCTPointAnnotationArray)
|
||||
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
||||
{
|
||||
[view setRegion:json ? [RCTConvert MKCoordinateRegion:json] : defaultView.region animated:YES];
|
||||
|
@ -50,6 +53,73 @@ RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
|||
|
||||
#pragma mark MKMapViewDelegate
|
||||
|
||||
|
||||
|
||||
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
|
||||
{
|
||||
if (![view.annotation isKindOfClass:[MKUserLocation class]]) {
|
||||
|
||||
RCTPointAnnotation *annotation = (RCTPointAnnotation *)view.annotation;
|
||||
NSString *title = view.annotation.title ?: @"";
|
||||
NSString *subtitle = view.annotation.subtitle ?: @"";
|
||||
|
||||
NSDictionary *event = @{
|
||||
@"target": mapView.reactTag,
|
||||
@"action": @"annotation-click",
|
||||
@"annotation": @{
|
||||
@"id": annotation.identifier,
|
||||
@"title": title,
|
||||
@"subtitle": subtitle,
|
||||
@"latitude": @(annotation.coordinate.latitude),
|
||||
@"longitude": @(annotation.coordinate.longitude)
|
||||
}
|
||||
};
|
||||
|
||||
[self.bridge.eventDispatcher sendInputEventWithName:@"topTap" body:event];
|
||||
}
|
||||
}
|
||||
|
||||
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(RCTPointAnnotation *)annotation
|
||||
{
|
||||
if ([annotation isKindOfClass:[MKUserLocation class]]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
MKPinAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"RCTAnnotation"];
|
||||
|
||||
annotationView.canShowCallout = true;
|
||||
annotationView.animatesDrop = annotation.animateDrop;
|
||||
|
||||
annotationView.leftCalloutAccessoryView = nil;
|
||||
if (annotation.hasLeftCallout) {
|
||||
annotationView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
|
||||
}
|
||||
|
||||
annotationView.rightCalloutAccessoryView = nil;
|
||||
if (annotation.hasRightCallout) {
|
||||
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
|
||||
}
|
||||
|
||||
return annotationView;
|
||||
}
|
||||
|
||||
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
|
||||
{
|
||||
// Pass to js
|
||||
RCTPointAnnotation *annotation = (RCTPointAnnotation *)view.annotation;
|
||||
NSString *side = (control == view.leftCalloutAccessoryView) ? @"left" : @"right";
|
||||
|
||||
NSDictionary *event = @{
|
||||
@"target": mapView.reactTag,
|
||||
@"side": side,
|
||||
@"action": @"callout-click",
|
||||
@"annotationId": annotation.identifier
|
||||
};
|
||||
|
||||
[self.bridge.eventDispatcher sendInputEventWithName:@"topTap" body:event];
|
||||
}
|
||||
|
||||
|
||||
- (void)mapView:(RCTMap *)mapView didUpdateUserLocation:(MKUserLocation *)location
|
||||
{
|
||||
if (mapView.followUserLocation) {
|
||||
|
@ -143,7 +213,7 @@ RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
|
|||
#define FLUSH_NAN(value) (isnan(value) ? 0 : value)
|
||||
|
||||
NSDictionary *event = @{
|
||||
@"target": [mapView reactTag],
|
||||
@"target": mapView.reactTag,
|
||||
@"continuous": @(continuous),
|
||||
@"region": @{
|
||||
@"latitude": @(FLUSH_NAN(region.center.latitude)),
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
//
|
||||
// RCTSegmentedControl.h
|
||||
// React
|
||||
//
|
||||
// Created by Clay Allsopp on 3/31/15.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
//
|
||||
// RCTSegmentedControl.m
|
||||
// React
|
||||
//
|
||||
// Created by Clay Allsopp on 3/31/15.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTSegmentedControl.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue