目前很多解耦方案,因为项目不算很大,所以选择了JLRoutes这种方式
首先封装了一个中间层,代码如下
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface RoutesMediator : NSObject
+ (instancetype)sharedInstance;
/**
页面跳转无参
@param url 目标页面的url
*/
- (void)openModuleWithURL:(NSURL *)url;
/**
页面跳转有参数
@param url 目标页面的url
*/
- (void)openModuleWithURLParameters:(NSURL *)url;
@end
NS_ASSUME_NONNULL_END
#import "RoutesMediator.h"
#import "JLRoutes.h"
#import "UIViewController+CurrentVC.h"
@interface RoutesMediator ()
@end
@implementation RoutesMediator
+ (instancetype)sharedInstance {
static RoutesMediator *mediator;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mediator = [[RoutesMediator alloc] init];
});
return mediator;
}
/**
无参路由注册
*/
- (void)registerModuleNoParameters {
[[JLRoutes globalRoutes] addRoute:@"/:module/:target/:Modal" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
return [self goTargetViewController:parameters isParam:NO];
}];
}
/**
有参路由注册
*/
- (void)registerModuleParameters {
[[JLRoutes globalRoutes] addRoute:@"/:module/:target/:Modal/:parameter" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
return [self goTargetViewController:parameters isParam:YES];
}];
}
/**
页面跳转
@param parameters 参数
@param isParam 是否有参数
@return Bool
*/
- (BOOL)goTargetViewController:(NSDictionary *)parameters isParam:(BOOL)isParam{
NSString *targetClassString = parameters[@"target"];
Class targetClass = NSClassFromString(targetClassString);
id object = [[targetClass alloc] init];
NSString *modal = parameters[@"Modal"];
// 有参数设置参数
if (isParam) {
if ([object respondsToSelector:@selector(setParameterJsonString:)]) {
[object performSelector:@selector(setParameterJsonString:) withObject:parameters[@"parameter"]];
}
}
if ([object isKindOfClass:[UIViewController class]]) {
// 目标视图控制器
UIViewController *taegetVC = (UIViewController *)object;
// 获取当前视图控制器
UIViewController *currentViewController = [UIViewController getCurrentViewController];
// Push
if ([modal isEqualToString:@"push"]) {
[currentViewController.navigationController pushViewController:taegetVC animated:YES];
}
else{
// present
if ([taegetVC respondsToSelector:@selector(setVCModal:)]) {
[taegetVC performSelector:@selector(setVCModal:) withObject:@"present"];
}
BaseNavigationController *nav = [[BaseNavigationController alloc]initWithRootViewController:taegetVC];
[currentViewController presentViewController:nav animated:YES completion:nil];
}
return YES;
} else {
return NO;
}
}
/**
页面跳转无参
@param url 目标页面的url
*/
- (void)openModuleWithURL:(NSURL *)url{
[self registerModuleNoParameters];
[self openUrl:url];
}
/**
页面跳转有参数
@param url 目标页面的url
*/
- (void)openModuleWithURLParameters:(NSURL *)url{
[self registerModuleParameters];
[self openUrl:url];
}
- (void)openUrl:(NSURL *)url{
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
if (success) {
[[JLRoutes globalRoutes] routeURL:url];
}
}];
}
@end
对外提供了两个方法
/**
页面跳转无参
@param url 目标页面的url
*/
- (void)openModuleWithURL:(NSURL *)url;
/**
页面跳转有参数
@param url 目标页面的url
*/
- (void)openModuleWithURLParameters:(NSURL *)url;
这两个方法分别调用
**
无参路由注册
*/
- (void)registerModuleNoParameters {
[[JLRoutes globalRoutes] addRoute:@"/:module/:target/:Modal" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
return [self goTargetViewController:parameters isParam:NO];
}];
}
module:就是功能模块的名字
target:需要跳转的ViewController名字
Modal:跳转方式是push还是present
/**
有参路由注册
*/
- (void)registerModuleParameters {
[[JLRoutes globalRoutes] addRoute:@"/:module/:target/:Modal/:parameter" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
return [self goTargetViewController:parameters isParam:YES];
}];
}
module:就是功能模块的名字
target:需要跳转的ViewController名字
Modal:跳转方式是push还是present
parameter:需要传递的参数
使用
无参push方式
NSURL *viewUrl = [NSURL URLWithString:@"JLRoutesDemo://MouduleA/ModuleADeatil1ViewController/push"];
[[RoutesMediator sharedInstance] openModuleWithURL:viewUrl];
注意:在跳转ModuleADeatil1ViewController中我们并不需要#improt"ModuleADeatil1ViewController.h"
传递参数
NSDictionary *dict = @{@"text" : @"传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传值传!!"
};
NSString *urlStr = [NSString stringWithFormat:@"JLRoutesDemo://MouduleA/ModuleADeatil2ViewController/push/%@",[JsonHelper dataTOjsonString:dict]];
// 有汉字需要转义
urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
[[RoutesMediator sharedInstance] openModuleWithURLParameters:[NSURL URLWithString:urlStr]];
设置info.plist
提示
没有写从B页面返回A页面回传参数这种方法,感觉一个页面一个页面的回传传参不是很好,可以注册通知,或者结合# Reactive Cocoa写比较好。
如果您有好的方式也可以提。
具体使用可以参考Demo
Demo