mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-28 12:15:37 +08:00
[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.  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:
@@ -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)),
|
||||
|
||||
Reference in New Issue
Block a user