Commit b0bda04f authored by Qiu Xiang's avatar Qiu Xiang

重构 iOS Marker

ref #7
parent 0a1c8064
...@@ -70,6 +70,7 @@ export default class MarkerExample extends Component { ...@@ -70,6 +70,7 @@ export default class MarkerExample extends Component {
/> />
<Marker <Marker
icon='green' icon='green'
onInfoWindowPress={this._handleCustomInfoWindowPress}
coordinate={{ coordinate={{
latitude: 39.806901, latitude: 39.806901,
longitude: 116.297972, longitude: 116.297972,
......
#import "AMapView.h" #import "AMapView.h"
#import "AMapOverlay.h" #import "AMapOverlay.h"
@interface AMapMarker : UIView <MAAnnotation, AMapOverlayDelegate> @interface AMapMarker : MAAnnotationView <MAAnnotation, AMapOverlayDelegate>
@property(nonatomic, copy) RCTBubblingEventBlock onPress; @property(nonatomic, copy) RCTBubblingEventBlock onPress;
@property(nonatomic, copy) RCTBubblingEventBlock onInfoWindowPress; @property(nonatomic, copy) RCTBubblingEventBlock onInfoWindowPress;
@property(nonatomic, copy) RCTBubblingEventBlock onDragStart; @property(nonatomic, copy) RCTBubblingEventBlock onDragStart;
@property(nonatomic, copy) RCTBubblingEventBlock onDrag; @property(nonatomic, copy) RCTBubblingEventBlock onDrag;
@property(nonatomic, copy) RCTBubblingEventBlock onDragEnd; @property(nonatomic, copy) RCTBubblingEventBlock onDragEnd;
@property(nonatomic, assign) BOOL dragging;
- (CLLocationCoordinate2D)coordinate;
- (NSString *)title;
- (NSString *)subtitle;
- (BOOL)active; - (BOOL)active;
- (MAAnnotationView *)annotationView; - (MAAnnotationView *)annotationView;
- (void)setMapView:(AMapView *)mapView; - (void)setMapView:(AMapView *)mapView;
- (void)setCoordinate:(CLLocationCoordinate2D)coordinate; - (void)updateActive;
@end @end
#import <React/UIView+React.h>
#import "AMapMarker.h" #import "AMapMarker.h"
#pragma ide diagnostic ignored "OCUnusedMethodInspection" #pragma ide diagnostic ignored "OCUnusedMethodInspection"
@implementation AMapMarker { @implementation AMapMarker {
MAAnnotationView *_annotationView;
MAPointAnnotation *_annotation; MAPointAnnotation *_annotation;
AMapOverlay *_marker; MAPinAnnotationView *_pinView;
MAPinAnnotationColor _pinColor;
MACustomCalloutView *_calloutView;
AMapOverlay *_callout; AMapOverlay *_callout;
AMapView *_mapView; AMapView *_mapView;
BOOL _active; BOOL _active;
NSString *_title;
NSString *_subtitle;
CLLocationCoordinate2D _coordinate;
MAPinAnnotationColor _pinColor;
BOOL _draggable;
NSInteger _zIndex;
} }
- (MAAnnotationView *)annotationView { - (instancetype)init {
return _annotationView; _annotation = [MAPointAnnotation new];
self = [super initWithAnnotation:_annotation reuseIdentifier:nil];
self.canShowCallout = YES;
[self addGestureRecognizer:[
[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_handleTap:)]];
return self;
} }
- (NSString *)title { - (NSString *)title {
return _title; return _annotation.title;
} }
- (NSString *)subtitle { - (NSString *)subtitle {
return _subtitle; return _annotation.subtitle;
} }
- (CLLocationCoordinate2D)coordinate { - (CLLocationCoordinate2D)coordinate {
return _coordinate; return _annotation.coordinate;
}
- (void)setCoordinate:(CLLocationCoordinate2D)coordinate {
_coordinate = coordinate;
_annotation.coordinate = coordinate;
} }
- (void)setTitle:(NSString *)title { - (void)setTitle:(NSString *)title {
_title = title;
_annotation.title = title; _annotation.title = title;
} }
- (void)setActive:(BOOL)active {
_active = active;
if (active) {
[_mapView selectAnnotation:self animated:YES];
} else {
[_mapView deselectAnnotation:self animated:YES];
}
}
- (void)setIcon:(MAPinAnnotationColor)color { - (void)setIcon:(MAPinAnnotationColor)color {
_pinColor = color; _pinColor = color;
((MAPinAnnotationView *) _annotationView).pinColor = color; _pinView.pinColor = color;
} }
- (void)setDescription:(NSString *)description { - (void)setDescription:(NSString *)description {
_subtitle = description;
_annotation.subtitle = description; _annotation.subtitle = description;
} }
- (void)setDraggable:(BOOL)draggable { - (void)setCoordinate:(CLLocationCoordinate2D)coordinate {
_draggable = draggable; _annotation.coordinate = coordinate;
_annotationView.draggable = draggable;
} }
- (void)setInfoWindowEnabled:(BOOL)enabled { - (void)setActive:(BOOL)active {
_annotationView.canShowCallout = enabled; _active = active;
_pinView.selected = active;
self.selected = active;
[self updateActive];
}
- (void)updateActive {
dispatch_async(dispatch_get_main_queue(), ^{
if (_active) {
[_mapView selectAnnotation:self animated:YES];
} else {
[_mapView deselectAnnotation:self animated:YES];
}
});
} }
- (void)setZIndex:(NSInteger)zIndex { - (void)setInfoWindowEnabled:(BOOL)enabled {
_zIndex = zIndex; _pinView.canShowCallout = enabled;
_annotationView.zIndex = zIndex; self.canShowCallout = enabled;
} }
- (void)setMapView:(AMapView *)mapView { - (void)setMapView:(AMapView *)mapView {
_mapView = mapView; _mapView = mapView;
} }
- (void)_handleTap:(UITapGestureRecognizer *)recognizer {
_active = YES;
[self updateActive];
if (self.onInfoWindowPress) {
self.onInfoWindowPress(@{});
}
}
- (BOOL)active { - (BOOL)active {
return _active; return _active;
} }
- (void)insertReactSubview:(id <RCTComponent>)subview atIndex:(NSInteger)atIndex { - (MAAnnotationView *)annotationView {
if (atIndex == 0) { if (self.reactSubviews.count == 0) {
_annotation = [MAPointAnnotation new]; if (_pinView == nil) {
_annotation.coordinate = _coordinate; _pinView = [[MAPinAnnotationView alloc] initWithAnnotation:_annotation reuseIdentifier:nil];
_annotation.title = _title; _pinView.canShowCallout = YES;
_annotation.subtitle = _subtitle; _pinView.draggable = self.draggable;
_pinView.pinColor = _pinColor;
if ([subview isKindOfClass:[AMapOverlay class]]) { _pinView.customCalloutView = _calloutView;
_marker = (AMapOverlay *) subview;
_marker.delegate = self;
_annotationView = [[MAAnnotationView alloc] initWithAnnotation:_annotation reuseIdentifier:nil];
} else {
_annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:_annotation reuseIdentifier:nil];
((MAPinAnnotationView *) _annotationView).pinColor = _pinColor;
} }
return _pinView;
} else {
return self;
}
}
_annotationView.canShowCallout = YES; - (void)insertReactSubview:(id <RCTComponent>)subview atIndex:(NSInteger)atIndex {
_annotationView.draggable = _draggable; if (atIndex == 0 && subview.reactSubviews.count > 0) {
_annotationView.zIndex = _zIndex; [super insertReactSubview:subview atIndex:atIndex];
} else if (atIndex == 1 && [subview isKindOfClass:[AMapOverlay class]]) { }
if (atIndex == 1 && [subview isKindOfClass:[AMapOverlay class]]) {
_callout = (AMapOverlay *) subview; _callout = (AMapOverlay *) subview;
_callout.delegate = self; _callout.delegate = self;
UIButton *button = [UIButton new]; UIButton *button = [UIButton new];
[button addSubview:_callout]; [button addSubview:_callout];
_annotationView.customCalloutView = [[MACustomCalloutView alloc] initWithCustomView:button]; _calloutView = [[MACustomCalloutView alloc] initWithCustomView:button];
self.customCalloutView = _calloutView;
} }
} }
- (void)didUpdateReactSubviews {
[super didUpdateReactSubviews];
self.bounds = self.reactSubviews[0].bounds;
}
#pragma mark AMapOverlayDelegate #pragma mark AMapOverlayDelegate
- (void)update:(AMapOverlay *)overlay { - (void)update:(AMapOverlay *)overlay {
if (self.dragging) { self.customCalloutView.bounds = overlay.bounds;
return;
}
CGFloat width = CGRectGetWidth(overlay.bounds);
CGFloat height = CGRectGetHeight(overlay.bounds);
if (overlay == _marker) {
UIGraphicsBeginImageContextWithOptions([_marker bounds].size, NO, 0.0f);
[_marker.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
_annotationView.image = image;
_annotationView.centerOffset = CGPointMake(0, -height / 2);
} else if (overlay == _callout) {
_annotationView.customCalloutView.bounds = CGRectMake(0, 0, width, height);
}
} }
@end @end
...@@ -9,5 +9,4 @@ ...@@ -9,5 +9,4 @@
@interface AMapOverlay : RCTView @interface AMapOverlay : RCTView
@property(nonatomic, strong) id <AMapOverlayDelegate> delegate; @property(nonatomic, strong) id <AMapOverlayDelegate> delegate;
- (void)update;
@end @end
#import <React/UIView+React.h>
#import "AMapOverlay.h" #import "AMapOverlay.h"
@implementation AMapOverlay { @implementation AMapOverlay {
} }
- (void)update { - (void)didUpdateReactSubviews {
[super didUpdateReactSubviews];
[self.delegate update:self]; [self.delegate update:self];
} }
......
...@@ -15,11 +15,6 @@ RCT_EXPORT_MODULE() ...@@ -15,11 +15,6 @@ RCT_EXPORT_MODULE()
return [AMapOverlay new]; return [AMapOverlay new];
} }
RCT_EXPORT_METHOD(update:(nonnull NSNumber *)reactTag) { RCT_EXPORT_METHOD(update:(nonnull NSNumber *)reactTag) {}
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
id view = viewRegistry[reactTag];
[(AMapOverlay *) view update];
}];
}
@end @end
...@@ -16,7 +16,6 @@ RCT_EXPORT_MODULE() ...@@ -16,7 +16,6 @@ RCT_EXPORT_MODULE()
- (UIView *)view { - (UIView *)view {
AMapView *mapView = [AMapView new]; AMapView *mapView = [AMapView new];
// when scroll view contains Map maybe we need stop Map Rending Cost.
mapView.runLoopMode = NSDefaultRunLoopMode; mapView.runLoopMode = NSDefaultRunLoopMode;
mapView.allowsAnnotationViewSorting = YES; mapView.allowsAnnotationViewSorting = YES;
mapView.centerCoordinate = CLLocationCoordinate2DMake(39.9042, 116.4074); mapView.centerCoordinate = CLLocationCoordinate2DMake(39.9042, 116.4074);
...@@ -105,13 +104,7 @@ RCT_EXPORT_METHOD(animateTo:(nonnull NSNumber *)reactTag params:(NSDictionary *) ...@@ -105,13 +104,7 @@ RCT_EXPORT_METHOD(animateTo:(nonnull NSNumber *)reactTag params:(NSDictionary *)
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id <MAAnnotation>)annotation { - (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id <MAAnnotation>)annotation {
if ([annotation isKindOfClass:[AMapMarker class]]) { if ([annotation isKindOfClass:[AMapMarker class]]) {
AMapMarker *marker = (AMapMarker *) annotation; AMapMarker *marker = (AMapMarker *) annotation;
if (marker.active) { [marker updateActive];
dispatch_async(dispatch_get_main_queue(), ^{
// directly call selectAnnotation not work, because of there has no current AnnotationView presentation.
// use RUNLOOP
[mapView selectAnnotation:marker animated:YES];
});
}
return marker.annotationView; return marker.annotationView;
} }
return nil; return nil;
...@@ -141,12 +134,10 @@ RCT_EXPORT_METHOD(animateTo:(nonnull NSNumber *)reactTag params:(NSDictionary *) ...@@ -141,12 +134,10 @@ RCT_EXPORT_METHOD(animateTo:(nonnull NSNumber *)reactTag params:(NSDictionary *)
- (void)mapView:(MAMapView *)mapView annotationView:(MAAnnotationView *)view didChangeDragState:(MAAnnotationViewDragState)newState - (void)mapView:(MAMapView *)mapView annotationView:(MAAnnotationView *)view didChangeDragState:(MAAnnotationViewDragState)newState
fromOldState:(MAAnnotationViewDragState)oldState { fromOldState:(MAAnnotationViewDragState)oldState {
AMapMarker *marker = (AMapMarker *) view.annotation; AMapMarker *marker = (AMapMarker *) view.annotation;
marker.dragging = NO;
if (newState == MAAnnotationViewDragStateStarting && marker.onDragStart) { if (newState == MAAnnotationViewDragStateStarting && marker.onDragStart) {
marker.onDragStart(@{}); marker.onDragStart(@{});
} }
if (newState == MAAnnotationViewDragStateDragging) { if (newState == MAAnnotationViewDragStateDragging) {
marker.dragging = YES;
if (marker.onDrag) { if (marker.onDrag) {
marker.onDrag(@{}); marker.onDrag(@{});
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment