美文网首页iOS技术点
iOS - 路由跳转页面Push 不用导入控制器头文件

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

作者: 东风不起尘 | 来源:发表于2019-10-28 14:39 被阅读0次

在项目开发中经常性的要跳转控制器,然而每次都要导入控制器的头文件 这样一来有点麻烦 故此有一些方法可以偷懒的办法(程序员就是要不但的“偷懒”才能进步不是吗) 进入正题吧 如何实现这样的功能了? 肯定少比了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控制器中就可以直接使用传过来的值了
是不是非常方便.......

相关文章

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

    在项目开发中经常性的要跳转控制器,然而每次都要导入控制器的头文件 这样一来有点麻烦 故此有一些方法可以偷懒的办法(...

  • 路由方案

    一: 路由 跳转 XXURLRouter 目的:做push 控制器跳转 一: 注册 目的:1设置路由地址 例如:...

  • IOS 页面切换

    写ios应用的页面切换不比写网页容易,网页应用可通过路由控制页面的跳转,而 ios 应用没有路由概念,所以页面跳转...

  • react路由跳转、传参

    1、路由的跳转 一、DOM跳转 在需要跳转的页面导入import {Link} from 'react-route...

  • Angular2 路由传值

    在接收值得组件里面导入ActivatedRoute 路由设置页面传参 父级页面路由跳转的实现 子页面的Compon...

  • Vue笔记

    1.vue文件之间使用路由跳转传值: this.$router.push({ path:'要跳转的页面路径',...

  • Vue

    1.函数路由跳转:this.$router.push('detail') 2. SEO 思路处理 Vue 单页面 ...

  • iOS加速计的简单使用

    导入头文件 iOS4之前 iOS5之后分成两种 push push方式:实时采集所有数据(采集频率高)创建运动管理...

  • 认识一下Flutter中Navigator数据传递原理

    引言 在Flutter中,路由间的页面跳转使用的是Navigator.push、Navigator.pop方法。 ...

  • iOS高仿微信图标编辑

    iOS高仿微信图标编辑 Installation Example 导入头文件 跳转 代理 涂鸦 表情 文字 裁剪 ...

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/zdkbvctx.html