繼 http://www.reibang.com/p/73a6acba45aa 之后的導(dǎo)航功能历葛。
線路規(guī)劃主要代碼:
//進(jìn)行路徑規(guī)劃
[self.driveManager calculateDriveRouteWithStartPoints:@[self.startPoint]
endPoints:@[self.endPoint]
wayPoints:nil
drivingStrategy:AMapNaviDrivingStrategySingleDefault];
接下來敘述項目配置:
1价匠、去高德開放平臺下載對應(yīng)的導(dǎo)航AMapNaviKit.framework并解壓
2当纱、將AMapNaviKit.framework拖入工程,記得選擇:
3踩窖、添加導(dǎo)航需要的資源文件 AMapNavi.bundle坡氯,如圖:
4、下面開始代碼部分:(自定義控制器,將下面的代碼復(fù)制進(jìn)控制器即可箫柳,只需要在上個控制器設(shè)置好CLLocationCoordinate2D coor手形、MAUserLocation *currentUL即可進(jìn)行導(dǎo)航功能)
在導(dǎo)航控制器.h文件導(dǎo)入頭文件#import <AMapNaviKit/AMapNaviKit.h>并添加幾個屬性:
@property (nonatomic, strong) AMapNaviDriveManager *driveManager;
@property (nonatomic, strong) AMapNaviDriveView *driveView;
@property (nonatomic, strong) MAUserLocation *currentUL;//導(dǎo)航起始位置,即用戶當(dāng)前的位置
@property (nonatomic, assign) CLLocationCoordinate2D coor;//導(dǎo)航終點位置
導(dǎo)航控制器.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
{
//設(shè)置導(dǎo)航的起點和終點
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添加為導(dǎo)航數(shù)據(jù)的Representative悯恍,使其可以接收到導(dǎo)航誘導(dǎo)數(shù)據(jù)
[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
{
//進(jìn)行路徑規(guī)劃
[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導(dǎo)航
[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
{
//停止導(dǎo)航
[self.driveManager stopNavi];
[self.driveManager removeDataRepresentative:self.driveView];
//停止語音
[[SpeechSynthesizer sharedSpeechSynthesizer] stopSpeak];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)driveViewMoreButtonClicked:(AMapNaviDriveView *)driveView
{
//配置MoreMenu狀態(tài)
[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];
}
在導(dǎo)航控制器.m文件中引用的#import "SpeechSynthesizer.h" 為導(dǎo)航時的語音功能库糠、
import "MoreMenuView.h"為偏好設(shè)置界面
SpeechSynthesizer.h文件內(nèi)容:
#import <AVFoundation/AVFoundation.h>
/**
* iOS7及以上版本可以使用 AVSpeechSynthesizer 合成語音
*
* 或者采用"科大訊飛"等第三方的語音合成服務(wù)
*/
@interface SpeechSynthesizer : NSObject
+ (instancetype)sharedSpeechSynthesizer;
- (void)speakString:(NSString *)string;
- (void)stopSpeak;
SpeechSynthesizer.m文件內(nèi)容:
@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以便可以在后臺播放聲音,更多細(xì)節(jié)參考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及以下版本系統(tǒng)上語速異常
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0)
{
aUtterance.rate = 0.25;//iOS7設(shè)置為0.25
}
else if ([[[UIDevice currentDevice] systemVersion] floatValue] < 9.0)
{
aUtterance.rate = 0.15;//iOS8設(shè)置為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文件內(nèi)容:
#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文件內(nèi)容:
#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 = @[@"偏好設(shè)置"];
_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];
}
}
至此涮毫,導(dǎo)航功能已經(jīng)完結(jié)瞬欧,如果感覺有幫助請打賞,歡迎評論罢防、點贊哦K一ⅰ!咒吐!??