代碼解耦-iOS應用內動態跳轉解決方案 Routable-iOS簡單使用

前言

在APP開發過程中,必然會遇到在WebView和推送消息中打開其他頁面的需求,進一步則是在任何動態界面.

但隨著APP越來越大,功能模塊越來越復雜,采用傳統的控制器跳轉方式,需要持有跳轉對象,就會造成復雜的依賴鏈,代碼耦合性變強.

采用Routable的方式進行動態界面跳轉則不會有這個問題.

傳統跳轉:

ProjectDetailViewController* pro = [[ProjectDetailViewController alloc]init];
pro.StrID = @"XX";
pro.Memo = @"XX";
[self.navigationController pushViewController:pro animated:YES];

Routable跳轉:

[[Routable sharedRouter] open:@"ProjectDetail/XX/XX"];

Routable使用

1.注冊協議

//一般在APP入口didFinishLaunchingWithOptions中進行注冊
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    //map規則 @"跳轉標識/:參數1/:參數2...."
    [[Routable sharedRouter] setNavigationController:nav];
    [[Routable sharedRouter] map:@"ProjectDetail/:StrID/:Memo/:Name" toController:[ProjectDetailViewController class]];
}

2.使用協議進行跳轉

//open規則 @"跳轉標識/參數1/參數2"
[[Routable sharedRouter] open:@"ProjectDetail/XX/XX"];

Routable代碼解析

關鍵方法:sharedRouter map open setNavigationController

sharedRouter方法:

//使用dispatch_once初始化單例對象 保證一個程序生命周期中使用同一個Router對象
+ (instancetype)sharedRouter {
  static Routable *_sharedRouter = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    _sharedRouter = [[Routable alloc] init];
  });
  return _sharedRouter;
}

map方法:

- (void)map:(NSString *)format toController:(Class)controllerClass withOptions:(UPRouterOptions *)options {
  if (!format) {
    @throw [NSException exceptionWithName:@"RouteNotProvided"
                                   reason:@"Route #format is not initialized"
                                 userInfo:nil];
    return;
  }
  if (!options) {
    options = [UPRouterOptions routerOptions];
  }
  options.openClass = controllerClass;
  //關鍵代碼 創建UPRouterOptions對象 將傳入的類對象作為value 參數字符串作為key存儲在可變字典
  [self.routes setObject:options forKey:format];
}

setNavigationController方法:

//Router對象中有一個navigationController參數 用來保存傳入的導航視圖控制器 在open方法中會使用這個導航視圖控制器進行跳轉
@property (readwrite, nonatomic, strong) UINavigationController *navigationController;

open方法:

//調用Router類中的該方法 將傳入的參數格式化成RouterParams對象
//再通過RouterParams對象從self.routes中獲取對應的openClass類對象
//使用navigationController進行跳轉
- (void)open:(NSString *)url
    animated:(BOOL)animated
 extraParams:(NSDictionary *)extraParams
{
  RouterParams *params = [self routerParamsForUrl:url extraParams: extraParams];
  UPRouterOptions *options = params.routerOptions;
  
  if (options.callback) {
    RouterOpenCallback callback = options.callback;
    callback([params controllerParams]);
    return;
  }
  
  if (!self.navigationController) {
    if (_ignoresExceptions) {
      return;
    }
    
    @throw [NSException exceptionWithName:@"NavigationControllerNotProvided"
                                   reason:@"Router#navigationController has not been set to a UINavigationController instance"
                                 userInfo:nil];
  }
  
  UIViewController *controller = [self controllerForRouterParams:params];
  
  if (self.navigationController.presentedViewController) {
    [self.navigationController dismissViewControllerAnimated:animated completion:nil];
  }
  
  if ([options isModal]) {
    if ([controller.class isSubclassOfClass:UINavigationController.class]) {
      [self.navigationController presentViewController:controller
                                              animated:animated
                                            completion:nil];
    }
    else {
      UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
      navigationController.modalPresentationStyle = controller.modalPresentationStyle;
      navigationController.modalTransitionStyle = controller.modalTransitionStyle;
      [self.navigationController presentViewController:navigationController
                                              animated:animated
                                            completion:nil];
    }
  }
  else if (options.shouldOpenAsRootViewController) {
    [self.navigationController setViewControllers:@[controller] animated:animated];
  }
  else {
    [self.navigationController pushViewController:controller animated:animated];
  }
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容