文档章节

使用runtime跳转界面

背锅侠
 背锅侠
发布于 2016/03/02 22:51
字数 659
阅读 64
收藏 2

在开发项目中,会有这样变态的需求:

  • 推送:根据服务端推送过来的数据规则,跳转到对应的控制器

  • feeds列表:不同类似的cell,可能跳转不同的控制器(嘘!产品经理是这样要求:我也不确定会跳转哪个界面哦,可能是这个又可能是那个,能给我做灵活吗?根据后台返回规则任意跳转?)

思考:wocao!这变态的需求,要拒绝他吗?

switch判断呗,考虑所有跳转的因素?这不得写死我...

switch () {
    case :
        break;
    default:
        break;
}

我是这么个实现的(runtime是个好东西)

利用runtime动态生成对象、属性、方法这特性,我们可以先跟服务端商量好,定义跳转规则,比如要跳转到A控制器,需要传属性id、type,那么服务端返回字典给我,里面有控制器名,两个属性名跟属性值,客户端就可以根据控制器名生成对象,再用kvc给对象赋值,这样就搞定了 ---O(∩_∩)O哈哈哈

比如:根据推送规则跳转对应界面HSFeedsViewController

HSFeedsViewController.h:

  • 进入该界面需要传的属性

@interface HSFeedsViewController : UIViewController
// 注:根据下面的两个属性,可以从服务器获取对应的频道列表数据
/** 频道ID */
@property (nonatomic, copy) NSString *ID;
/** 频道type */
@property (nonatomic, copy) NSString *type;
@end

AppDelegate.m:

  • 推送过来的消息规则

// 这个规则肯定事先跟服务端沟通好,跳转对应的界面需要对应的参数
NSDictionary *userInfo = @{
                           @"class": @"HSFeedsViewController",
                           @"property": @{
                                        @"ID": @"123",
                                        @"type": @"12"
                                   }
                           };

  接收推送消息

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [self push:userInfo];
}

 跳转界面

- (void)push:(NSDictionary *)params
{
    // 类名
    NSString *class =[NSString stringWithFormat:@"%@", params[@"class"]];
    const char *className = [class cStringUsingEncoding:NSASCIIStringEncoding];
    // 从一个字串返回一个类
    Class newClass = objc_getClass(className);
    if (!newClass)
    {
        // 创建一个类
        Class superClass = [NSObject class];
        newClass = objc_allocateClassPair(superClass, className, 0);
        // 注册你创建的这个类
        objc_registerClassPair(newClass);
    }
    // 创建对象
    id instance = [[newClass alloc] init];
    // 对该对象赋值属性
    NSDictionary * propertys = params[@"property"];
    [propertys enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        // 检测这个对象是否存在该属性
        if ([self checkIsExistPropertyWithInstance:instance verifyPropertyName:key]) {
            // 利用kvc赋值
            [instance setValue:obj forKey:key];
        }
    }];
    // 获取导航控制器
    UITabBarController *tabVC = (UITabBarController *)self.window.rootViewController;
    UINavigationController *pushClassStance = (UINavigationController *)tabVC.viewControllers[tabVC.selectedIndex];
    // 跳转到对应的控制器
    [pushClassStance pushViewController:instance animated:YES];
}

检测对象是否存在该属性

- (BOOL)checkIsExistPropertyWithInstance:(id)instance verifyPropertyName:(NSString *)verifyPropertyName
{
    unsigned int outCount, i;
    // 获取对象里的属性列表
    objc_property_t * properties = class_copyPropertyList([instance
                                                           class], &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property =properties[i];
        //  属性名转成字符串
        NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
        // 判断该属性是否存在
        if ([propertyName isEqualToString:verifyPropertyName]) {
            free(properties);
            return YES;
        }
    }
    free(properties);
    return NO;
}


© 著作权归作者所有

共有 人打赏支持
上一篇: BAT面试笔记
背锅侠

背锅侠

粉丝 10
博文 18
码字总数 13050
作品 0
东城
CTO(技术副总裁)
私信 提问
ionic之页面跳转的两种方式-yellowcong

在ionic中,页面条状主要有两种方式,1、通过在界面中的方式,2、通过代码的方式跳转,绑定事件,通过调用这个事件的同时,我们可以在这个里面添加参数的传递,主要依赖于 这两个组建 代码地址...

yelllowcong
02/24
0
0
iOS VIPER架构实践(三):面向接口的路由设计

路由是实现模块间解耦的一个有效工具。如果要进行组件化开发,路由是必不可少的一部分。目前iOS上绝大部分的路由工具都是基于URL匹配的,优缺点都很明显。这篇文章里将会给出一个更加原生和安...

黑超熊猫zuik
2017/09/27
0
0
解耦神器 —— 统跳协议和Rewrite引擎

以前写过简单实现APP内各模块界面跳转统一使用URL的文章,今天发现一篇手机天猫的同学写的统跳方案的文章,写的很好,转载和大家分享。 ------------------------------------分割线-------...

xingjm8511
2016/12/03
36
0
数据通信解耦框架 - Dilutions

Dilutions Dilutions是一个专门用于模块间数据协议通信的解耦协议框架,提供高性能数据分析和通信功能,解耦多项目多模块间的数据通信,简化代码逻辑成本。 通过一段URI字符串就能实现所有操作...

林小萌萌
06/01
0
0
5行代码搞定全屏Pop转场

原文出处: DoublesZ 最近在写论文阶段, 没有足够的精力来写技术分享, 再此说声抱歉, 不过我也会尽力挤出时间不定期为大家更新一些干货的!! 请大家继续关注!! POP全屏转场 好了, 今天要分享的...

hejunbinlan
2016/07/18
18
0

没有更多内容

加载失败,请刷新页面

加载更多

Idea

command + E : 打开最近编辑过的文件 command + O : 打开指定文件 option + enter: 补全变量 实现接口 格式化字符串 System.out.printf("realName:" + u.getRealName() + "email: " + u.get...

xpttxsok
18分钟前
0
0
FTP 协议 1.0

自己制作的FTP协议:

Explorer0
28分钟前
2
0
Android 通过DrawableInflater加载自定义Drawable

一、Drawable 在Android系统张,图形图像的绘制需要在画布上进行操作和处理,但是绘制需要了解很多细节以及可能要进行一些复杂的处理,因此系统提供了一个被称之为Drawable的类来进行绘制处理...

IamOkay
40分钟前
1
0
灵活无处安放,所以选择流浪....《漆黑的空间》& 《灰色轨迹》

灵活无处安放,所以选择流浪....《漆黑的空间》& 《灰色轨迹》

yizhichao
46分钟前
1
0
Kafka+Flink 实现准实时异常检测系统

1.背景介绍 异常检测可以定义为“基于行动者(人或机器)的行为是否正常作出决策”,这项技术可以应用于非常多的行业中,比如金融场景中做交易检测、贷款检测;工业场景中做生产线预警;安防...

架构师springboot
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部