iOS 万能跳转界面方法 (runtime实用篇一)

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

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

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

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

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

1
2
3
4
5
6
switch  () {
     case  :
         break ;
     default :
         break ;
}

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

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

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

HSFeedsViewController.h:

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

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

AppDelegate.m:

  • 推送过来的消息规则

1
2
3
4
5
6
7
8
// 这个规则肯定事先跟服务端沟通好,跳转对应的界面需要对应的参数
NSDictionary *userInfo = @{
                            @ "class" : @ "HSFeedsViewController" ,
                            @ "property" : @{
                                         @ "ID" : @ "123" ,
                                         @ "type" : @ "12"
                                    }
                            };
  • 接收推送消息

1
2
3
4
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
     [self push:userInfo];
}
  • 跳转界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- (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];
}
  • 检测对象是否存在该属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (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;
}

具体使用和代码: https://github.com/HHuiHao/Universal-Jump-ViewController

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值