ios万能跳转界面方法(Runtime)

957 阅读2分钟

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

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

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

switch判断呗,考虑所有跳转的因素?

switch() {

case:

break;

default:

break;

}

或者if else…

虽然可以解决 但是太过于麻烦  有10种跳转的可能 就要定义10种类型

老的方式 如下:

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

进入该界面需要传的属性

#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController

@property (nonatomic, strong) NSString *titleName;

@end

推送或者是跳转的消息规则

NSDictionary *firstDict = @{

@"class":@"FirstViewController",

@"property":@{

@"titleName":@"first"

}

};

跳转界面

NSDictionary *info = self.allSelectArray[indexPath.row];

// 类名

NSString *class = [NSString stringWithFormat:@"%@",info[@"class"]];

const char *className = [class cStringUsingEncoding:NSASCIIStringEncoding];

// 通过名称转化为类

Class newClass = NSClassFromString(class);

// 判断得到这个类,是否存在

if (!newClass) {

// 创建一个类

Class superClass = [NSObject class];

newClass = objc_allocateClassPair(superClass, className, 0);

// 注册这个类

objc_registerClassPair(newClass);

}

// 创建对象

id instance = [[newClass alloc] init];

// 对该对象赋值属性

NSDictionary *propertys = info[@"property"];

[propertys enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {

if ([self checkIsExistPropertuWithInsance:instance verityPropertyName:key]) {

// 利用KVC赋值

[instance setValue:obj forKey:key];

}

}];

// 获取导航控制器

[self.navigationController pushViewController:instance animated:YES];

推送中获取导航控制器

// 获取导航控制器

UITabBarController *tabVC = (UITabBarController *)self.window.rootViewController;

UINavigationController *pushClassStance = (UINavigationController *)tabVC.viewControllers[tabVC.selectedIndex];

// 跳转到对应的控制器

[pushClassStance pushViewController:instance animated:YES];

检测对象是否存在该属性

// 检查对象是否存在这个属性

- (BOOL)checkIsExistPropertuWithInsance:(id)instance verityPropertyName:(NSString *)verityPropertyName

{

unsigned int outCount;

// 获取对象的属性列表

objc_property_t *properties = class_copyPropertyList([instance class], &outCount);

for (int i= 0; i < outCount; i++) {

objc_property_t property = properties[i];

// 属性名转为字符成

NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];

// 判断该属性是否存在

if ([propertyName isEqualToString:verityPropertyName]) {

free(properties);

return YES;

}

}

free(properties);

return NO;

}

demol

参考博客:

http://www.cocoachina.com/ios/20150824/13104.html

http://blog.csdn.net/sike2008/article/details/50164961