Commit 8445e74f authored by 7c00's avatar 7c00

简单实现 iOS 导航功能

parent b155b9ec
// @flow
import React, {PropTypes, PureComponent} from 'react'
import {
ViewPropTypes,
UIManager,
requireNativeComponent,
findNodeHandle,
} from 'react-native'
import {LatLng} from './PropTypes'
export default class Navigation extends PureComponent {
static propTypes = {
...ViewPropTypes,
/**
* 路径规划成功事件
*/
onCalculateRouteSuccess: React.PropTypes.func,
/**
* 路径规划失败事件
*/
onCalculateRouteFailure: React.PropTypes.func,
}
/**
* 步行路线规划
*/
calculateWalkRoute(start, end) {
this._sendCommand('calculateWalkRoute', [start, end])
}
/**
* 骑行路线规划
*/
calculateRideRoute(start, end) {
this._sendCommand('calculateRideRoute', [start, end])
}
/**
* 驾车路线规划
*/
calculateDriveRoute(start, end) {
this._sendCommand('calculateDriveRoute', [start, end])
}
/**
* 开始导航
*/
start() {
this._sendCommand('start')
}
/**
* call native method
*
* @private
*/
_sendCommand(command: string, params?: []) {
UIManager.dispatchViewManagerCommand(
findNodeHandle(this),
UIManager.AMapNavigation.Commands[command],
params,
)
}
render() {
return <AMapNavigation {...this.props}/>
}
}
const AMapNavigation = requireNativeComponent('AMapNavigation', Navigation)
PODS: PODS:
- AMap3DMap (5.2.1): - AMap3DMap (5.3.0):
- AMapFoundation (~> 1.3) - AMapFoundation (~> 1.3)
- AMapFoundation (1.4.1) - AMapFoundation (1.4.2)
- AMapNavi (5.2.1):
- AMap3DMap (>= 5.2.1)
- AMapFoundation (~> 1.4)
- React (0.47.1): - React (0.47.1):
- React/Core (= 0.47.1) - React/Core (= 0.47.1)
- react-native-amap3d (0.2.3): - react-native-amap3d (0.2.5):
- AMap3DMap - AMapNavi
- React - React
- React/Core (0.47.1): - React/Core (0.47.1):
- Yoga (= 0.47.1.React) - Yoga (= 0.47.1.React)
...@@ -25,12 +28,13 @@ EXTERNAL SOURCES: ...@@ -25,12 +28,13 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga/" :path: "../node_modules/react-native/ReactCommon/yoga/"
SPEC CHECKSUMS: SPEC CHECKSUMS:
AMap3DMap: 5a98d7c08d23a7f07853e7ee2fa7650057b75896 AMap3DMap: 0614b5b7ed7a8b69f1d9ba7bc40ce30362497dc5
AMapFoundation: 9cc5198980873cca29bb70466a84b3bd922c0e65 AMapFoundation: 6c0471c9a6a0ad17dad46e3d800ad56ca170f82a
AMapNavi: bb4d65295ed0ee0ad4b5f5792e9e2ea0e5117ffa
React: f705239a901cb3f95445c34468e5b37b6f80a0d4 React: f705239a901cb3f95445c34468e5b37b6f80a0d4
react-native-amap3d: 8a112ada1085c3703ea4122ce55145bdccb84897 react-native-amap3d: 8e0233de49453f31abd40479ce728c3535400f9f
Yoga: 13a12502dfabb4c75b914071dcb542af800deed4 Yoga: 13a12502dfabb4c75b914071dcb542af800deed4
PODFILE CHECKSUM: 532b8476f224a7e69d8d5ec4a246f7ed1173a8e1 PODFILE CHECKSUM: 532b8476f224a7e69d8d5ec4a246f7ed1173a8e1
COCOAPODS: 1.2.1 COCOAPODS: 1.2.0
...@@ -28,6 +28,10 @@ export default class Examples extends Component { ...@@ -28,6 +28,10 @@ export default class Examples extends Component {
</Touchable> </Touchable>
} }
componentDidMount() {
this.props.navigation.navigate('Navigation')
}
render() { render() {
return <ScrollView style={styles.scrollView} contentContainerStyle={styles.container}> return <ScrollView style={styles.scrollView} contentContainerStyle={styles.container}>
<StatusBar barStyle='dark-content' backgroundColor='#e0e0e0'/> <StatusBar barStyle='dark-content' backgroundColor='#e0e0e0'/>
...@@ -45,8 +49,6 @@ export default class Examples extends Component { ...@@ -45,8 +49,6 @@ export default class Examples extends Component {
{this._renderItem('动画移动', 'Animated')} {this._renderItem('动画移动', 'Animated')}
<View style={styles.separator}/> <View style={styles.separator}/>
{this._renderItem('地图事件', 'Events')} {this._renderItem('地图事件', 'Events')}
<View style={styles.separator}/>
{this._renderItem('导航', 'Navigation')}
</View> </View>
<View style={styles.group}> <View style={styles.group}>
{this._renderItem('添加标记', 'Marker')} {this._renderItem('添加标记', 'Marker')}
...@@ -57,6 +59,9 @@ export default class Examples extends Component { ...@@ -57,6 +59,9 @@ export default class Examples extends Component {
<View style={styles.separator}/> <View style={styles.separator}/>
{this._renderItem('绘制圆形', 'Circle')} {this._renderItem('绘制圆形', 'Circle')}
</View> </View>
<View style={styles.group}>
{this._renderItem('导航', 'Navigation')}
</View>
</ScrollView> </ScrollView>
} }
} }
...@@ -81,6 +86,7 @@ const styles = StyleSheet.create({ ...@@ -81,6 +86,7 @@ const styles = StyleSheet.create({
}, },
separator: { separator: {
height: StyleSheet.hairlineWidth, height: StyleSheet.hairlineWidth,
backgroundColor: '#eee',
}, },
itemText: { itemText: {
fontSize: 16, fontSize: 16,
......
...@@ -7,7 +7,7 @@ export default class NavigationExample extends Component { ...@@ -7,7 +7,7 @@ export default class NavigationExample extends Component {
title: '导航', title: '导航',
} }
_ready = () => { componentDidMount() {
this._navigation.calculateDriveRoute( this._navigation.calculateDriveRoute(
{ {
latitude: 39.906901, latitude: 39.906901,
...@@ -26,7 +26,6 @@ export default class NavigationExample extends Component { ...@@ -26,7 +26,6 @@ export default class NavigationExample extends Component {
return <Navigation return <Navigation
ref={ref => this._navigation = ref} ref={ref => this._navigation = ref}
style={StyleSheet.absoluteFill} style={StyleSheet.absoluteFill}
onReady={this._ready}
onCalculateRouteSuccess={this._start} onCalculateRouteSuccess={this._start}
/> />
} }
......
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
_active = YES; _active = YES;
[self updateActive]; [self updateActive];
if (self.onInfoWindowPress) { if (self.onInfoWindowPress) {
self.onInfoWindowPress(@{}); self.onInfoWindowPress(nil);
} }
} }
......
#import <AMapNaviKit/AMapNaviDriveView.h>
#import <React/RCTComponent.h>
@interface AMapNavigation : AMapNaviDriveView
@property(nonatomic, copy) RCTBubblingEventBlock onCalculateRouteSuccess;
@end
\ No newline at end of file
#import "AMapNavigation.h"
@implementation AMapNavigation {
}
@end
\ No newline at end of file
#import <React/RCTUIManager.h>
#import <AMapNaviKit/AMapNaviDriveView.h>
#import <AMapNaviKit/AMapNaviDriveManager.h>
#import "AMapNavigation.h"
#pragma ide diagnostic ignored "OCUnusedClassInspection"
@interface AMapNavigationManager : RCTViewManager <AMapNaviDriveManagerDelegate>
+ (AMapNavigation *)driveView;
+ (AMapNaviDriveManager *)driveManager;
@end
@implementation AMapNavigationManager {
AMapNavigation *_driveView;
AMapNaviDriveManager *_driveManager;
}
- (instancetype)init {
if (self = [super init]) {
_driveView = [AMapNavigationManager driveView];
_driveManager = [AMapNavigationManager driveManager];
_driveManager.delegate = self;
}
return self;
}
RCT_EXPORT_MODULE()
RCT_EXPORT_VIEW_PROPERTY(onCalculateRouteSuccess, RCTBubblingEventBlock)
RCT_EXPORT_METHOD(calculateDriveRoute:(nonnull NSNumber *)reactTag start:(AMapNaviPoint *)start endPoints:(AMapNaviPoint *)end) {
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
[_driveManager calculateDriveRouteWithStartPoints:@[start]
endPoints:@[end]
wayPoints:nil
drivingStrategy:AMapNaviDrivingStrategySingleDefault];
}];
}
RCT_EXPORT_METHOD(start:(nonnull NSNumber *)reactTag) {
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
[_driveManager startGPSNavi];
}];
}
- (UIView *)view {
return _driveView;
}
- (void)driveManagerOnCalculateRouteSuccess:(AMapNaviDriveManager *)driveManager {
if (_driveView.onCalculateRouteSuccess) {
_driveView.onCalculateRouteSuccess(nil);
}
}
+ (AMapNaviDriveManager *)driveManager {
static AMapNaviDriveManager *driveManager;
if (driveManager == nil) {
driveManager = [AMapNaviDriveManager new];
[driveManager addDataRepresentative:[AMapNavigationManager driveView]];
}
return driveManager;
}
+ (AMapNavigation *)driveView {
static AMapNavigation *driveView;
if (driveView == nil) {
driveView = [AMapNavigation new];
}
return driveView;
}
@end
#import <MAMapKit/MAMapKit.h> #import <MAMapKit/MAMapKit.h>
#import <React/RCTComponent.h>
@interface AMapView : MAMapView @interface AMapView : MAMapView
......
...@@ -121,7 +121,7 @@ RCT_EXPORT_METHOD(animateTo:(nonnull NSNumber *)reactTag params:(NSDictionary *) ...@@ -121,7 +121,7 @@ RCT_EXPORT_METHOD(animateTo:(nonnull NSNumber *)reactTag params:(NSDictionary *)
if ([view.annotation isKindOfClass:[AMapMarker class]]) { if ([view.annotation isKindOfClass:[AMapMarker class]]) {
AMapMarker *marker = (AMapMarker *) view.annotation; AMapMarker *marker = (AMapMarker *) view.annotation;
if (marker.onPress) { if (marker.onPress) {
marker.onPress(@{}); marker.onPress(nil);
} }
} }
} }
...@@ -137,7 +137,7 @@ RCT_EXPORT_METHOD(animateTo:(nonnull NSNumber *)reactTag params:(NSDictionary *) ...@@ -137,7 +137,7 @@ RCT_EXPORT_METHOD(animateTo:(nonnull NSNumber *)reactTag params:(NSDictionary *)
if ([view.annotation isKindOfClass:[AMapMarker class]]) { if ([view.annotation isKindOfClass:[AMapMarker class]]) {
AMapMarker *marker = (AMapMarker *) view.annotation; AMapMarker *marker = (AMapMarker *) view.annotation;
if (marker.onInfoWindowPress) { if (marker.onInfoWindowPress) {
marker.onInfoWindowPress(@{}); marker.onInfoWindowPress(nil);
} }
} }
} }
...@@ -146,11 +146,11 @@ RCT_EXPORT_METHOD(animateTo:(nonnull NSNumber *)reactTag params:(NSDictionary *) ...@@ -146,11 +146,11 @@ RCT_EXPORT_METHOD(animateTo:(nonnull NSNumber *)reactTag params:(NSDictionary *)
fromOldState:(MAAnnotationViewDragState)oldState { fromOldState:(MAAnnotationViewDragState)oldState {
AMapMarker *marker = (AMapMarker *) view.annotation; AMapMarker *marker = (AMapMarker *) view.annotation;
if (newState == MAAnnotationViewDragStateStarting && marker.onDragStart) { if (newState == MAAnnotationViewDragStateStarting && marker.onDragStart) {
marker.onDragStart(@{}); marker.onDragStart(nil);
} }
if (newState == MAAnnotationViewDragStateDragging) { if (newState == MAAnnotationViewDragStateDragging) {
if (marker.onDrag) { if (marker.onDrag) {
marker.onDrag(@{}); marker.onDrag(nil);
} }
} }
if (newState == MAAnnotationViewDragStateEnding && marker.onDragEnd) { if (newState == MAAnnotationViewDragStateEnding && marker.onDragEnd) {
......
#import <MAMapKit/MAMapView.h> #import <MAMapKit/MAMapView.h>
#import <AMapNaviKit/AMapNaviCommonObj.h>
#import <React/RCTConvert.h> #import <React/RCTConvert.h>
#import <React/RCTConvert+CoreLocation.h> #import <React/RCTConvert+CoreLocation.h>
#import "Coordinate.h" #import "Coordinate.h"
...@@ -31,6 +32,12 @@ RCT_ENUM_CONVERTER(MAPinAnnotationColor, (@{ ...@@ -31,6 +32,12 @@ RCT_ENUM_CONVERTER(MAPinAnnotationColor, (@{
[self CLLocationDegrees:json[@"longitudeDelta"]])); [self CLLocationDegrees:json[@"longitudeDelta"]]));
} }
+ (AMapNaviPoint *)AMapNaviPoint:(id)json {
return [AMapNaviPoint
locationWithLatitude:[self CGFloat:json[@"latitude"]]
longitude:[self CGFloat:json[@"longitude"]]];
}
RCT_ARRAY_CONVERTER(Coordinate) RCT_ARRAY_CONVERTER(Coordinate)
@end @end
...@@ -16,5 +16,5 @@ Pod::Spec.new do |s| ...@@ -16,5 +16,5 @@ Pod::Spec.new do |s|
s.source_files = 'ios/**/*.{h,m}' s.source_files = 'ios/**/*.{h,m}'
s.dependency 'React' s.dependency 'React'
s.dependency 'AMap3DMap' s.dependency 'AMapNavi'
end end
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