在项目开发中经常性的要跳转控制器,然而每次都要导入控制器的头文件 这样一来有点麻烦 故此有一些方法可以偷懒的办法(程序员就是要不但的“偷懒”才能进步不是吗) 进入正题吧 如何实现这样的功能了? 肯定少比了runtime的事了
一.新建一个文件如下:RDRouterManager.h
//
// RDRouterManager.h
// RD
//
// Created by 易东 on 2019/10/18.
// Copyright © 2019 易东. All rights reserved.
//
import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef void(^RDRouterBlock) (id backData);
@protocol RDRouterManagerDelegate <NSObject>
@optional
//可以用字典 传一些属性值
- (void)loadParam:(NSDictionary *)parameters;
@end
/// 路由的管理
@interface UIViewController(RDRouterManager)<RDRouterManagerDelegate>
@property (nonatomic,copy,nullable)RDRouterBlock lhz_RouterBlock;
-
(void)pushViewControllerName:(NSString *)vcName;
-
(void)pushViewControllerName:(NSString *)vcName
animated:(BOOL)animated; -
(void)pushViewControllerName:(NSString *)vcName
param:(NSDictionary *)aParam; -
(void)pushViewControllerName:(NSString *)vcName
param:(NSDictionary *)aParam
routerBlock:(RDRouterBlock)routerBlock; -
(void)pushViewControllerName:(NSString *)vcName
param:(NSDictionary *)aParam
animated:(BOOL)animated
routerBlock:(RDRouterBlock)routerBlock;
@end
NS_ASSUME_NONNULL_END
二.实现文件如下:RDRouterManager.m
import "RDRouterManager.h"
import <objc/runtime.h>
//这个是导航栏控制器的基类 可以使用你们自己封装的
import "BaseNavigationController.h"
typedef enum : NSUInteger {
RDRouterTypePush,
RDRouterTypePresent
} RDRouterType;
pragma clang diagnostic push
pragma clang diagnostic ignored "-Wnonnull"
@implementation UIViewController(RDRouterManager)
pragma mark ---- 属性赋值
-
(void)paramToVc:(UIViewController *) v param:(NSDictionary *)parameters{
if (parameters) {
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];
}
}
}
} -
(void)pushViewControllerName:(NSString * __nonnull)vcName {
[self pushViewControllerName:vcName
param:nil
animated:YES
routerBlock:nil];
} -
(void)pushViewControllerName:(NSString * __nonnull)vcName
animated:(BOOL)animated {
[self pushViewControllerName:vcName
param:nil
animated:animated
routerBlock:nil];
} -
(void)pushViewControllerName:(NSString * __nonnull)vcName
param:(NSDictionary *)aParam {
[self pushViewControllerName:vcName
param:aParam
animated:YES
routerBlock:nil];
} -
(void)pushViewControllerName:(NSString * __nonnull)vcName
param:(NSDictionary * __nullable)aParam
animated:(BOOL)animated {
[self pushViewControllerName:vcName
param:aParam
animated:animated
routerBlock:nil];
} -
(void)pushViewControllerName:(NSString *)vcName
param:(NSDictionary *)aParam
routerBlock:(RDRouterBlock)routerBlock {
[self routerViewControllerName:vcName
param:aParam
routerType:RDRouterTypePush
animated:YES
routerBlock:routerBlock];
}
-
(void)pushViewControllerName:(NSString *)vcName
param:(NSDictionary *)aParam
animated:(BOOL)animated
routerBlock:(RDRouterBlock)routerBlock {
[self routerViewControllerName:vcName
param:aParam
routerType:RDRouterTypePush
animated:animated
routerBlock:routerBlock];
} -
(void)presentViewControllerName:(NSString *)vcName
param:(NSDictionary *)aParam
animated:(BOOL)animated
routerBlock:(RDRouterBlock)routerBlock {
[self routerViewControllerName:vcName
param:aParam
routerType:RDRouterTypePresent
animated:animated
routerBlock:routerBlock];
}
-
(void)routerViewControllerName:(NSString * __nonnull)vcName
param:(NSDictionary * __nullable)aParam
routerType:(RDRouterType)rType
animated:(BOOL)animated
routerBlock:(RDRouterBlock)routerBlock{
//跳转
//获取控制器
Class cls = NSClassFromString(vcName);
if (!cls) {
return;
}
UIViewController *vc = [[cls alloc] init];//参数解析
[self paramToVc:vc param:aParam];
if ([self respondsToSelector:@selector(loadParam:)]) {
[self loadParam:aParam];
}if (rType == RDRouterTypePush) {
if ([self isKindOfClass:[UINavigationController class]]) {
//当前控制器本身就是一个导航控制器
[(UINavigationController *)self pushViewController:vc animated:animated];}else { //控制器存在堆栈中 if (self.navigationController) { [self.navigationController pushViewController:vc animated:animated]; } }
}else {
BaseNavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:vc];
if ([self isKindOfClass:[UINavigationController class]]) {
//当前控制器本身就是一个导航控制器
[(UINavigationController *)self presentViewController:nav animated:animated completion:nil];
}else {
//控制器存在堆栈中
if (self.navigationController) {
[self.navigationController presentViewController:nav animated:animated completion:nil];
}else {
[self presentViewController:nav animated:animated completion:nil];
}
}
}
if (routerBlock) {
[vc setLhz_RouterBlock:routerBlock];
}
}
pragma clang diagnostic pop
static char JZTCallBackBlockKey;
-
(void)setLhz_RouterBlock:(RDRouterBlock)lhz_RouterBlock {
objc_setAssociatedObject(self, &JZTCallBackBlockKey, lhz_RouterBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
} -
(RDRouterBlock)lhz_RouterBlock{
return objc_getAssociatedObject(self, &JZTCallBackBlockKey);
}
@end
三.调用事例:
1.[self.navigationController pushViewControllerName:@"xxxVC" animated:YES];
2.[self.navigationController pushViewControllerName:@"xxxVC" param:@{@"model":xxx}];
xxxVC控制器中有属性指model 可以用字典传值 在xxxVC控制器中就可以直接使用传过来的值了
是不是非常方便.......
网友评论