【iOS】高德地图MAMapKit的使用:导航功能。
2017-03-10 本文已影响2945人
attackGiant
继 http://www.jianshu.com/p/73a6acba45aa 之后的导航功能。
93039.png线路规划主要代码:
//进行路径规划
[self.driveManager calculateDriveRouteWithStartPoints:@[self.startPoint]
endPoints:@[self.endPoint]
wayPoints:nil
drivingStrategy:AMapNaviDrivingStrategySingleDefault];
接下来叙述项目配置:
1、去高德开放平台下载对应的导航AMapNaviKit.framework并解压
2、将AMapNaviKit.framework拖入工程,记得选择:
121212.png3、添加导航需要的资源文件 AMapNavi.bundle,如图:
223.png 323.png4、下面开始代码部分:(自定义控制器,将下面的代码复制进控制器即可,只需要在上个控制器设置好CLLocationCoordinate2D coor、MAUserLocation *currentUL即可进行导航功能)
在导航控制器.h文件导入头文件#import <AMapNaviKit/AMapNaviKit.h>并添加几个属性:
@property (nonatomic, strong) AMapNaviDriveManager *driveManager;
@property (nonatomic, strong) AMapNaviDriveView *driveView;
@property (nonatomic, strong) MAUserLocation *currentUL;//导航起始位置,即用户当前的位置
@property (nonatomic, assign) CLLocationCoordinate2D coor;//导航终点位置
导航控制器.m文件:
#import "SpeechSynthesizer.h"
#import "MoreMenuView.h"
@interface GPSNaviViewController ()<AMapNaviDriveManagerDelegate, AMapNaviDriveViewDelegate, MoreMenuViewDelegate>
@property (nonatomic, strong) AMapNaviPoint *startPoint;
@property (nonatomic, strong) AMapNaviPoint *endPoint;
@property (nonatomic, strong) MoreMenuView *moreMenu;
@end
@implementation GPSNaviViewController
#pragma mark - Life Cycle
- (void)viewDidLoad
{
[super viewDidLoad];
// [self setNavigationBackItem];
[self initProperties];
[self initDriveView];
[self initDriveManager];
[self initMoreMenu];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = YES;
self.navigationController.toolbarHidden = YES;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self calculateRoute];
}
- (void)viewWillLayoutSubviews
{
UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0)
{
interfaceOrientation = self.interfaceOrientation;
}
if (UIInterfaceOrientationIsPortrait(interfaceOrientation))
{
[self.driveView setIsLandscape:NO];
}
else if (UIInterfaceOrientationIsLandscape(interfaceOrientation))
{
[self.driveView setIsLandscape:YES];
}
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
#pragma mark - Initalization
- (void)initProperties
{
//设置导航的起点和终点
self.startPoint = [AMapNaviPoint locationWithLatitude:_currentUL.coordinate.latitude longitude:_currentUL.coordinate.longitude];
self.endPoint = [AMapNaviPoint locationWithLatitude:_coor.latitude longitude:_coor.longitude];
}
- (void)initDriveManager
{
if (self.driveManager == nil)
{
self.driveManager = [[AMapNaviDriveManager alloc] init];
[self.driveManager setDelegate:self];
[self.driveManager setAllowsBackgroundLocationUpdates:YES];
[self.driveManager setPausesLocationUpdatesAutomatically:NO];
//将driveView添加为导航数据的Representative,使其可以接收到导航诱导数据
[self.driveManager addDataRepresentative:self.driveView];
}
}
- (void)initDriveView
{
if (self.driveView == nil)
{
self.driveView = [[AMapNaviDriveView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
self.driveView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
[self.driveView setDelegate:self];
[self.view addSubview:self.driveView];
}
}
- (void)initMoreMenu
{
if (self.moreMenu == nil)
{
self.moreMenu = [[MoreMenuView alloc] init];
self.moreMenu.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
[self.moreMenu setDelegate:self];
}
}
#pragma mark - Route Plan
- (void)calculateRoute
{
//进行路径规划
[self.driveManager calculateDriveRouteWithStartPoints:@[self.startPoint]
endPoints:@[self.endPoint]
wayPoints:nil
drivingStrategy:AMapNaviDrivingStrategySingleDefault];
}
#pragma mark - AMapNaviDriveManager Delegate
- (void)driveManager:(AMapNaviDriveManager *)driveManager error:(NSError *)error
{
NSLog(@"error:{%ld - %@}", (long)error.code, error.localizedDescription);
}
- (void)driveManagerOnCalculateRouteSuccess:(AMapNaviDriveManager *)driveManager
{
NSLog(@"onCalculateRouteSuccess");
//算路成功后开始GPS导航
[self.driveManager startGPSNavi];
}
- (void)driveManager:(AMapNaviDriveManager *)driveManager onCalculateRouteFailure:(NSError *)error
{
NSLog(@"onCalculateRouteFailure:{%ld - %@}", (long)error.code, error.localizedDescription);
}
- (void)driveManager:(AMapNaviDriveManager *)driveManager didStartNavi:(AMapNaviMode)naviMode
{
NSLog(@"didStartNavi");
}
- (void)driveManagerNeedRecalculateRouteForYaw:(AMapNaviDriveManager *)driveManager
{
NSLog(@"needRecalculateRouteForYaw");
}
- (void)driveManagerNeedRecalculateRouteForTrafficJam:(AMapNaviDriveManager *)driveManager
{
NSLog(@"needRecalculateRouteForTrafficJam");
}
- (void)driveManager:(AMapNaviDriveManager *)driveManager onArrivedWayPoint:(int)wayPointIndex
{
NSLog(@"onArrivedWayPoint:%d", wayPointIndex);
}
- (void)driveManager:(AMapNaviDriveManager *)driveManager playNaviSoundString:(NSString *)soundString soundStringType:(AMapNaviSoundType)soundStringType
{
NSLog(@"playNaviSoundString:{%ld:%@}", (long)soundStringType, soundString);
[[SpeechSynthesizer sharedSpeechSynthesizer] speakString:soundString];
}
- (void)driveManagerDidEndEmulatorNavi:(AMapNaviDriveManager *)driveManager
{
NSLog(@"didEndEmulatorNavi");
}
- (void)driveManagerOnArrivedDestination:(AMapNaviDriveManager *)driveManager
{
NSLog(@"onArrivedDestination");
}
#pragma mark - AMapNaviWalkViewDelegate
- (void)driveViewCloseButtonClicked:(AMapNaviDriveView *)driveView
{
//停止导航
[self.driveManager stopNavi];
[self.driveManager removeDataRepresentative:self.driveView];
//停止语音
[[SpeechSynthesizer sharedSpeechSynthesizer] stopSpeak];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)driveViewMoreButtonClicked:(AMapNaviDriveView *)driveView
{
//配置MoreMenu状态
[self.moreMenu setTrackingMode:self.driveView.trackingMode];
[self.moreMenu setShowNightType:self.driveView.showStandardNightType];
[self.moreMenu setFrame:self.view.bounds];
[self.view addSubview:self.moreMenu];
}
- (void)driveViewTrunIndicatorViewTapped:(AMapNaviDriveView *)driveView
{
NSLog(@"TrunIndicatorViewTapped");
}
- (void)driveView:(AMapNaviDriveView *)driveView didChangeShowMode:(AMapNaviDriveViewShowMode)showMode
{
NSLog(@"didChangeShowMode:%ld", (long)showMode);
}
#pragma mark - MoreMenu Delegate
- (void)moreMenuViewFinishButtonClicked
{
[self.moreMenu removeFromSuperview];
}
- (void)moreMenuViewNightTypeChangeTo:(BOOL)isShowNightType
{
[self.driveView setShowStandardNightType:isShowNightType];
}
- (void)moreMenuViewTrackingModeChangeTo:(AMapNaviViewTrackingMode)trackingMode
{
[self.driveView setTrackingMode:trackingMode];
}
在导航控制器.m文件中引用的#import "SpeechSynthesizer.h" 为导航时的语音功能、
import "MoreMenuView.h"为偏好设置界面
0383.pngSpeechSynthesizer.h文件内容:
#import <AVFoundation/AVFoundation.h>
/**
* iOS7及以上版本可以使用 AVSpeechSynthesizer 合成语音
*
* 或者采用"科大讯飞"等第三方的语音合成服务
*/
@interface SpeechSynthesizer : NSObject
+ (instancetype)sharedSpeechSynthesizer;
- (void)speakString:(NSString *)string;
- (void)stopSpeak;
SpeechSynthesizer.m文件内容:
@interface SpeechSynthesizer () <AVSpeechSynthesizerDelegate>
@property (nonatomic, strong, readwrite) AVSpeechSynthesizer *speechSynthesizer;
@end
@implementation SpeechSynthesizer
+ (instancetype)sharedSpeechSynthesizer
{
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[SpeechSynthesizer alloc] init];
});
return sharedInstance;
}
- (instancetype)init
{
if (self = [super init])
{
[self buildSpeechSynthesizer];
}
return self;
}
- (void)buildSpeechSynthesizer
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0)
{
return;
}
//简单配置一个AVAudioSession以便可以在后台播放声音,更多细节参考AVFoundation官方文档
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:NULL];
self.speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
[self.speechSynthesizer setDelegate:self];
}
- (void)speakString:(NSString *)string
{
if (self.speechSynthesizer)
{
AVSpeechUtterance *aUtterance = [AVSpeechUtterance speechUtteranceWithString:string];
[aUtterance setVoice:[AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"]];
//iOS语音合成在iOS8及以下版本系统上语速异常
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0)
{
aUtterance.rate = 0.25;//iOS7设置为0.25
}
else if ([[[UIDevice currentDevice] systemVersion] floatValue] < 9.0)
{
aUtterance.rate = 0.15;//iOS8设置为0.15
}
if ([self.speechSynthesizer isSpeaking])
{
[self.speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryWord];
}
[self.speechSynthesizer speakUtterance:aUtterance];
}
}
- (void)stopSpeak
{
if (self.speechSynthesizer)
{
[self.speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
}
}
MoreMenuView.h文件内容:
#import <AMapNaviKit/AMapNaviCommonObj.h>
@protocol MoreMenuViewDelegate;
@interface MoreMenuView : UIView
@property (nonatomic, assign) id<MoreMenuViewDelegate> delegate;
@property (nonatomic, assign) AMapNaviViewTrackingMode trackingMode;
@property (nonatomic, assign) BOOL showNightType;
@end
@protocol MoreMenuViewDelegate <NSObject>
@optional
- (void)moreMenuViewFinishButtonClicked;
- (void)moreMenuViewTrackingModeChangeTo:(AMapNaviViewTrackingMode)trackingMode;
- (void)moreMenuViewNightTypeChangeTo:(BOOL)isShowNightType;
MoreMenuView.m文件内容:
#define kFinishButtonHeight 40.0f
#define kOptionTableViewHieght 200.0f
#define kTableViewHeaderHeight 30.0f
#define kTableViewCellHeight 50.0f
@interface MoreMenuView ()<UITableViewDataSource, UITableViewDelegate>
{
UIView *_maskView;
UITableView *_optionTableView;
NSArray *_sections;
NSArray *_options;
UISegmentedControl *_viewModeSeg;
UISegmentedControl *_nightTypeSeg;
UIButton *_finishButton;
}
@end
@implementation MoreMenuView
@synthesize trackingMode = _trackingMode;
@synthesize showNightType = _showNightType;
#pragma mark - Initialization
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
self.backgroundColor = [UIColor clearColor];
[self initProperties];
[self createMoreMenuView];
}
return self;
}
- (void)initProperties
{
_sections = @[@"偏好设置"];
_options = @[@[@"跟随模式", @"昼夜模式"]];
}
- (void)createMoreMenuView
{
[self initMaskView];
[self initTableView];
[self initFinishButton];
}
- (void)initMaskView
{
_maskView = [[UIView alloc] initWithFrame:self.bounds];
_maskView.backgroundColor = [UIColor grayColor];
_maskView.alpha = 0.5;
_maskView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self addSubview:_maskView];
}
- (void)initTableView
{
_optionTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.bounds) - kFinishButtonHeight - kOptionTableViewHieght, CGRectGetWidth(self.bounds), kOptionTableViewHieght)
style:UITableViewStylePlain];
_optionTableView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
_optionTableView.backgroundColor = [UIColor whiteColor];
_optionTableView.delegate = self;
_optionTableView.dataSource = self;
_optionTableView.allowsSelection = NO;
[self addSubview:_optionTableView];
}
- (void)initFinishButton
{
_finishButton = [[UIButton alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.bounds) - kFinishButtonHeight, CGRectGetWidth(self.bounds), kFinishButtonHeight)];
_finishButton.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
[_finishButton setBackgroundColor:[UIColor blueColor]];
[_finishButton setTitle:@"完 成" forState:UIControlStateNormal];
[_finishButton addTarget:self action:@selector(finishButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_finishButton];
}
#pragma mark - TableView Delegate
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return kTableViewHeaderHeight;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return kTableViewCellHeight;
}
#pragma mark - TableView DataSource Delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return _sections.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return _sections[section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_options[section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *optionName = _options[indexPath.section][indexPath.row];
if ([optionName isEqualToString:@"跟随模式"])
{
return [self tableViewCellForViewMode];
}
else if ([optionName isEqualToString:@"昼夜模式"])
{
return [self tableViewCellForNightType];
}
return nil;
}
#pragma mark - Custom TableView Cell
- (UITableViewCell *)tableViewCellForViewMode
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ViewModeCellIdentifier"];
_viewModeSeg = [[UISegmentedControl alloc] initWithItems:@[@"正北朝上" , @"车头朝上"]];
[_viewModeSeg setFrame:CGRectMake(160, (kTableViewCellHeight - 30)/2.0, 150, 30)];
_viewModeSeg.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[_viewModeSeg setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} forState:UIControlStateNormal];
[_viewModeSeg addTarget:self action:@selector(viewModeSegmentedControlAction:) forControlEvents:UIControlEventValueChanged];
UILabel *optionNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, 120, kTableViewCellHeight)];
optionNameLabel.textAlignment = NSTextAlignmentLeft;
optionNameLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
optionNameLabel.font = [UIFont systemFontOfSize:18];
optionNameLabel.text = @"跟随模式:";
if (self.trackingMode == AMapNaviViewTrackingModeMapNorth)
{
[_viewModeSeg setSelectedSegmentIndex:0];
}
else if (self.trackingMode == AMapNaviViewTrackingModeCarNorth)
{
[_viewModeSeg setSelectedSegmentIndex:1];
}
[cell.contentView addSubview:optionNameLabel];
[cell.contentView addSubview:_viewModeSeg];
return cell;
}
- (UITableViewCell *)tableViewCellForNightType
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ViewModeCellIdentifier"];
UILabel *optionNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, 120, kTableViewCellHeight)];
optionNameLabel.textAlignment = NSTextAlignmentLeft;
optionNameLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
optionNameLabel.font = [UIFont systemFontOfSize:18];
optionNameLabel.text = @"昼夜模式:";
_nightTypeSeg = [[UISegmentedControl alloc] initWithItems:@[@"白天" , @"黑夜"]];
_nightTypeSeg.frame = CGRectMake(160, (kTableViewCellHeight - 30)/2.0, 150, 30);
_nightTypeSeg.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[_nightTypeSeg setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} forState:UIControlStateNormal];
[_nightTypeSeg addTarget:self action:@selector(nightTypeSegmentedControlAction:) forControlEvents:UIControlEventValueChanged];
[_nightTypeSeg setSelectedSegmentIndex:self.showNightType];
[cell.contentView addSubview:optionNameLabel];
[cell.contentView addSubview:_nightTypeSeg];
return cell;
}
#pragma mark - UISegmentedControl Action
- (void)viewModeSegmentedControlAction:(id)sender
{
NSInteger selectedIndex = [(UISegmentedControl *)sender selectedSegmentIndex];
if (self.delegate && [self.delegate respondsToSelector:@selector(moreMenuViewTrackingModeChangeTo:)])
{
[self.delegate moreMenuViewTrackingModeChangeTo:(AMapNaviViewTrackingMode)selectedIndex];
}
}
- (void)nightTypeSegmentedControlAction:(id)sender
{
NSInteger selectedIndex = [(UISegmentedControl *)sender selectedSegmentIndex];
if (self.delegate && [self.delegate respondsToSelector:@selector(moreMenuViewNightTypeChangeTo:)])
{
[self.delegate moreMenuViewNightTypeChangeTo:selectedIndex];
}
}
#pragma mark - Finish Button Action
- (void)finishButtonAction:(id)sender
{
if (self.delegate && [self.delegate respondsToSelector:@selector(moreMenuViewFinishButtonClicked)])
{
[self.delegate moreMenuViewFinishButtonClicked];
}
}
至此,导航功能已经完结,如果感觉有帮助请打赏,欢迎评论、点赞哦!!!☺☺