美文网首页
代码解耦-iOS应用內动态跳转解决方案 Routable-iOS

代码解耦-iOS应用內动态跳转解决方案 Routable-iOS

作者: sands_yu | 来源:发表于2017-02-23 10:30 被阅读715次
    title: 代码解耦-iOS应用內动态跳转解决方案 Routable-iOS简单使用 
    tags: [iOS,开发,APP]
    

    前言

    在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];
      }
    }
    
    

    相关文章

      网友评论

          本文标题:代码解耦-iOS应用內动态跳转解决方案 Routable-iOS

          本文链接:https://www.haomeiwen.com/subject/djgvwttx.html