iOS - 路由跳转页面Push 不用导入控制器头文件

在项目开发中经常性的要跳转控制器,然而每次都要导入控制器的头文件 这样一来有点麻烦 故此有一些方法可以偷懒的办法(程序员就是要不但的“偷懒”才能进步不是吗) 进入正题吧 如何实现这样的功能了? 肯定少比了runtime的事了

一.新建一个文件如下:RDRouterManager.h
//
// RDRouterManager.h
// RD
//
// Created by 易东 on 2019/10/18.
// Copyright © 2019 易东. All rights reserved.
//

import

NS_ASSUME_NONNULL_BEGIN

typedef void(^RDRouterBlock) (id backData);

@protocol RDRouterManagerDelegate

@optional
//可以用字典 传一些属性值

  • (void)loadParam:(NSDictionary *)parameters;

@end

/// 路由的管理

@interface UIViewController(RDRouterManager)

@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

//这个是导航栏控制器的基类 可以使用你们自己封装的

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控制器中就可以直接使用传过来的值了
是不是非常方便.......

你可能感兴趣的:(iOS - 路由跳转页面Push 不用导入控制器头文件)