描述
ALE中,地圖定位模式包括普通導(dǎo)覽模式、普通定位模式、普通指向模式、導(dǎo)航模式、導(dǎo)航指向模式、導(dǎo)航導(dǎo)覽模式。
模式切換的時(shí)機(jī)有兩種:點(diǎn)擊模式切換按鈕、操作地圖畫面。
- 點(diǎn)擊模式切換按鈕時(shí),地圖模式如下變換、
- 普通導(dǎo)覽模式 ? 普通定位模式 ? 普通指向模式
- 導(dǎo)航導(dǎo)覽模式 ? 導(dǎo)航模式 ? 導(dǎo)航指向模式
- 操作地圖時(shí),地圖模式如下變換
- 普通定位模式/普通指向模式 ? 普通導(dǎo)覽模式
- 導(dǎo)航模式/導(dǎo)航指向模式 ? 導(dǎo)航導(dǎo)覽模式
狀態(tài)流轉(zhuǎn)參照下圖

方案
使用 狀態(tài)模式 來(lái)實(shí)現(xiàn)狀態(tài)流轉(zhuǎn)。
使用 觀察者模式 來(lái)監(jiān)聽狀態(tài)變化,并根據(jù)具體的地圖模式進(jìn)行特定的UI展現(xiàn)。
地圖基礎(chǔ)狀態(tài)中除了包含一個(gè)表示地圖模式的屬性外,還包含具體流轉(zhuǎn)定義兩種操作方法,分別對(duì)應(yīng)點(diǎn)擊模式切換按鈕和操作地圖。
@class EepMSVGMapMode;
//地圖模式基類
@interface EepMSVGMapDisplayModeState : NSObject
@property (nonatomic, assign) EepMSVGMapDisplayMode mapMode;//地圖模式的屬性
-(void)handleMapWithContext:(EepMSVGMapMode*)context;//操作地圖
-(void)modeSwitchWithContext:(EepMSVGMapMode*)context;//按鈕切換模式
@end
業(yè)務(wù)中的具體模式繼承基礎(chǔ)狀態(tài)模式,重寫兩種操作對(duì)應(yīng)的流轉(zhuǎn)方法,修改相應(yīng)的屬性值。比如導(dǎo)航普通模式的實(shí)現(xiàn)細(xì)節(jié)如下:
//導(dǎo)航-普通模式
@implementation EepMSVGMapDisplayModeNavigationNormalState
-(instancetype)init{
self = [super init];
self.mapMode = EepMSVGMapDisplayModeNavigationNormal;
return self;
}
-(void)handleMapWithContext:(EepMSVGMapMode*)context{
context.mapState = [[EepMSVGMapDisplayModeNavigationTourGuideState alloc] init];
}
-(void)modeSwitchWithContext:(EepMSVGMapMode*)context{
context.mapState = [[EepMSVGMapDisplayModeNavigationDirectionState alloc] init];
}
@end
此處需要注意的是普通導(dǎo)覽模式和導(dǎo)航導(dǎo)覽模式下,操作地圖的時(shí)候,地圖模式不會(huì)發(fā)生變更,兩個(gè)狀態(tài)對(duì)應(yīng)的實(shí)現(xiàn)類可以將 handleMapWithContext: 方法hook,或者干脆不重寫該方法
對(duì)外通過(guò)以下訪問(wèn)形式;調(diào)用者不需要關(guān)心當(dāng)前模式是什么,只需要在點(diǎn)擊模式切換時(shí)和操作地圖時(shí),調(diào)用特定名稱的方法即可。
/**
* 地圖展示
**/
@interface EepMSVGMapMode : NSObject
@property (nonatomic,strong) EepMSVGMapDisplayModeState* mapState;
+(instancetype)sharedInstance;
-(void)setMapMode:(EepMSVGMapDisplayMode)mapMode;
//當(dāng)前地圖模式
-(EepMSVGMapDisplayMode)currentMapMode;
//操作地圖
-(void)handleMap;
//點(diǎn)擊了模式切換按鈕
-(void)modeSwitch;
@end
實(shí)現(xiàn)相當(dāng)簡(jiǎn)單,比如對(duì)于操作地圖接口,只需要調(diào)用當(dāng)前狀態(tài)的 handleMapWithContext:方法即可。
-(void)handleMap{
[self.mapState handleMapWithContext:self];
[[NSNotificationCenter defaultCenter] lt_postNotificationOnMainThreadName:ALEMapDisplayModeChangeKey object:nil];
}