美文网首页
Router跳转

Router跳转

作者: 宙斯YY | 来源:发表于2017-12-19 17:31 被阅读17次

ios APP跳转发生在这么几个地方:
1.APP内部UIViewController之间。
2.APP跳转其他APP。
3.从网页,推送或者其他APP跳转到APP指定页面。

//1.APP内部UIViewController之间
 ViewController2 * vc = [[ViewController2 alloc]init];
  [self.navigationController pushViewController:vc animated:YES];
//或者
//[self presentViewController:vc animated:YES completion:nil];

//2.APP跳转其他APP
  NSURL * url = [NSURL URLWithString:@"TestJLRouter2://abc"];
    if([[UIApplication sharedApplication]canOpenURL:url])
    {
        [[UIApplication sharedApplication] openURL:url options:[NSDictionary dictionary] completionHandler:^(BOOL success) {

        }];
    }

//3.AppDelegate的代理方法会被调用,可以根据url进行匹配
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options

我们会发现代码分散且不统一,我们想到使用Mediator模式统一处理这些跳转逻辑,github上比较优秀的作品是JLRoutesHHRouter
他们的思路基本上都是做一个Map,注册控制器到Map,并通过字符串匹配,进行跳转。

使用HHRouter

//在AppDelegate中注册控制器
[[HHRouter shared]map:@"ViewController" toControllerClass:ViewController.class];

//1.APP内部UIViewController之间,有点在于不需要#import"ViewController"
UIViewController * vc = [[HHRouter shared]matchController:@"ViewController"];
 [self.navigationController pushViewController:vc animated:YES];

//2.同传统方法

使用JLRoutes

//在AppDelegate中注册控制器并重写openURL
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[JLRoutes globalRoutes]addRoute:@"/NaviPush/:controller/:param" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        NSLog(@"parameters:%@",parameters);
        UIViewController *currentVc = [self currentViewController];
        UIViewController *v = [[NSClassFromString(parameters[@"controller"]) alloc] init];
        [self paramToVc:v param:parameters];
        [currentVc.navigationController pushViewController:v animated:YES];
        return YES;
    }];
}

//在该代理方法中做统一处理,不管是内部跳转还是外部跳过来,都会来到该代理
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
    NSLog(@"url:%@-%@",url,self.class);
    
    return [JLRoutes routeURL:url];
    
}

-(UIViewController *)currentViewController{
    
    UIViewController * currVC = nil;
    UIViewController * Rootvc = self.window.rootViewController ;
    do {
        if ([Rootvc isKindOfClass:[UINavigationController class]]) {
            UINavigationController * nav = (UINavigationController *)Rootvc;
            UIViewController * v = [nav.viewControllers lastObject];
            currVC = v;
            Rootvc = v.presentedViewController;
            continue;
        }else if([Rootvc isKindOfClass:[UITabBarController class]]){
            UITabBarController * tabVC = (UITabBarController *)Rootvc;
            currVC = tabVC;
            Rootvc = [tabVC.viewControllers objectAtIndex:tabVC.selectedIndex];
            continue;
        }
    } while (Rootvc!=nil);
    
    return currVC;
}


-(void)paramToVc:(UIViewController *) v param:(NSDictionary<NSString *,NSString *> *)parameters{
    //        runtime将参数传递至需要跳转的控制器
    unsigned int outCount = 0;
    objc_property_t * properties = class_copyPropertyList(v.class , &outCount);
    for (int i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        NSString *key = [NSString stringWithUTF8String:property_getName(property)];
        NSString *param = parameters[key];
        if (param != nil) {
            [v setValue:param forKey:key];
        }
    }
}

//1.APP内部UIViewController之间并传递参数
NSString *customURL =[NSString stringWithFormat:@"TestRouter://NaviPush/ViewController3/zsy?age=22"];
    
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL] options:@{} completionHandler:nil];

//2.同传统方法

相关文章

网友评论

      本文标题:Router跳转

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