前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS 路由改进

iOS 路由改进

作者头像
赵哥窟
发布2021-04-26 10:52:20
5590
发布2021-04-26 10:52:20
举报
文章被收录于专栏:日常技术分享日常技术分享

之前写过一篇关于iOS 组件化之CTMediator的文章,小项目中使用起来还是不怎么方便,改进了下,取名为DRouter吧,目录结构是这样的

截屏2021-04-23 15.45.46.png

DRouter

这个两个文件就不说了,就是CTMediator源文件改下名字,代码是一样的

Target_Commons

看代码就知道就是动态添加参数和回调的,CTMediator是在每个Module下面都添加一个Target_xxxx,这样觉得麻烦就写一个通用的。

代码语言:javascript
复制
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

extern NSString * const DRouterTargetCommons;

@interface Target_Commons : NSObject

// 自定义push方法
- (UIViewController *)Action_Push_CommonController:(NSDictionary *)params;

@end

NS_ASSUME_NONNULL_END
代码语言:javascript
复制
#import "Target_Commons.h"
#import "UIViewController+Parameter.h"
#import "UIViewController+Block.h"
#import <objc/runtime.h>

typedef void (^callBlock)(NSDictionary *);


NSString * const DRouterTargetCommons = @"Commons";

@implementation Target_Commons


// 自定义push方法
- (UIViewController *)Action_Push_CommonController:(NSDictionary *)params{
    NSString *vcClassName = params[@"vcClassName"];
    
    callBlock callback = params[@"callback"];
    
    Class class = NSClassFromString(vcClassName);
    UIViewController *controller = [[class alloc] init];
    //传值
    if([params objectForKey:@"vauleParameter"] != nil){
        controller.parameter = [params objectForKey:@"vauleParameter"];
    }
    //参数回调
    if(callback != nil){
        controller.backBlock = ^(NSDictionary * _Nonnull parameter) {
            callback(parameter);
        };
    }
    
    return controller;
}


@end
UIViewController+Parameter

分类给Controller添加参数用的

代码语言:javascript
复制
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIViewController (Parameter)

@property (copy, nonatomic) NSDictionary *parameter;

@end

NS_ASSUME_NONNULL_END
代码语言:javascript
复制
#import "UIViewController+Parameter.h"
#import <objc/runtime.h>

static const char * PARAMETER_KEY = "parameter_key";

@implementation UIViewController (Parameter)

- (void)setParameter:(NSDictionary *)parameter{
    objc_setAssociatedObject(self, PARAMETER_KEY, parameter, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSDictionary *)parameter {
    return  objc_getAssociatedObject(self, PARAMETER_KEY);
}


@end
UIViewController+Block

给Controller添加回调用的

代码语言:javascript
复制
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

typedef  void (^BackBlock)(NSDictionary *parameter);

@interface UIViewController (Block)

/** 完成的回调block */
@property (nonatomic, copy) BackBlock backBlock;

@end

NS_ASSUME_NONNULL_END
代码语言:javascript
复制
#import "UIViewController+Block.h"
#import <objc/runtime.h>

static const char * BLOCK_KEY = "block_key";

@implementation UIViewController (Block)

- (void)setBackBlock:(BackBlock)backBlock{
    objc_setAssociatedObject(self, BLOCK_KEY, backBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (BackBlock)backBlock {
    return  objc_getAssociatedObject(self, BLOCK_KEY);
}

@end
具体使用

截屏2021-04-23 15.52.38.png

如果图,每个Module还是新建一个Mediator

代码语言:javascript
复制
#import "DRouter.h"

NS_ASSUME_NONNULL_BEGIN

@interface DRouter (A_Module)

- (UIViewController *)mediator_AModulePage1:(NSMutableDictionary *)params;

- (UIViewController *)mediator_AModulePage1:(NSMutableDictionary *)params completion:(void (^)(NSDictionary *))completion;

@end

NS_ASSUME_NONNULL_END
代码语言:javascript
复制
#import "DRouter+A_Module.h"

//  字符串 是类名 Target_xxx.h 中的 xxx 部分
NSString * const kMediatorTarget_A_Module = @"A_Module";

@implementation DRouter (A_Module)

- (UIViewController *)mediator_AModulePage1:(NSMutableDictionary *)params{
    UIViewController *viewController = [self performTarget:@"Commons"
                                                    action:@"Action_Push_CommonController"
                                                    params:params shouldCacheTarget:NO];
    if ([viewController isKindOfClass:[UIViewController class]]) {
        // view controller 交付出去之后,可以由外界选择是push还是present
        return viewController;
    } else {
        // 这里处理异常场景,具体如何处理取决于产品
        NSLog(@"%@ 未能实例化页面", NSStringFromSelector(_cmd));
        return [[UIViewController alloc] init];
    }
}

- (UIViewController *)mediator_AModulePage1:(NSMutableDictionary *)params completion:(void (^)(NSDictionary *))completion{
    [params setValue:completion forKey:@"callback"];
    return [self mediator_AModulePage1:params];
}

@end
Controller中使用
代码语言:javascript
复制
- (void)pushAModulePage1
{
    NSMutableDictionary *param = [NSMutableDictionary dictionary];
    [param setValue:@"APage1Controller" forKey:@"vcClassName"];
    //需要回调时添加
    [param setValue:@"callback" forKey:@"callback"];
    //需要传值是添加
    [param setValue:@{@"value":@"我是上一个页面传过来的value"} forKey:@"vauleParameter"];
    
    UIViewController *viewController = [[DRouter sharedInstance]mediator_AModulePage1:param completion:^(NSDictionary * _Nonnull dic) {
        [self showAlert:[dic objectForKey:@"value"]];
        
    }];
   [self.navigationController pushViewController:viewController animated:YES];
}
返回参数
代码语言:javascript
复制
- (IBAction)blockAction:(UIButton *)sender {
    
    if(self.backBlock){
        [self.navigationController popViewControllerAnimated:YES];
        
        self.backBlock(@{@"value":@"A_Module_Page1_Block"});
    }else{
        [self.navigationController popViewControllerAnimated:YES];
    }
}

可以看到,我们在跳转并没有#import 需要跳转的页面。都是动态创建,传参和返回参数的。

下载地址

Demo

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • DRouter
  • Target_Commons
  • UIViewController+Parameter
  • UIViewController+Block
  • 具体使用
  • Controller中使用
  • 返回参数
    • 下载地址
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档