目前很多解耦方案,因為項目不算很大,所以選擇了JLRoutes這種方式
首先封裝了一個中間層,代碼如下
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface RoutesMediator : NSObject
+ (instancetype)sharedInstance;
/**
頁面跳轉無參
@param url 目標頁面的url
*/
- (void)openModuleWithURL:(NSURL *)url;
/**
頁面跳轉有參數(shù)
@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 參數(shù)
@param isParam 是否有參數(shù)
@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"];
// 有參數(shù)設置參數(shù)
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];
}
/**
頁面跳轉有參數(shù)
@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;
/**
頁面跳轉有參數(shù)
@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:需要傳遞的參數(shù)
使用
無參push方式
NSURL *viewUrl = [NSURL URLWithString:@"JLRoutesDemo://MouduleA/ModuleADeatil1ViewController/push"];
[[RoutesMediator sharedInstance] openModuleWithURL:viewUrl];
注意:在跳轉ModuleADeatil1ViewController中我們并不需要#improt"ModuleADeatil1ViewController.h"
傳遞參數(shù)
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
屏幕快照 2019-01-30 16.40.26.png
提示
沒有寫從B頁面返回A頁面回傳參數(shù)這種方法,感覺一個頁面一個頁面的回傳傳參不是很好,可以注冊通知,或者結合# Reactive Cocoa寫比較好。
如果您有好的方式也可以提。
具體使用可以參考Demo
Demo