相信大家是不是遇到过推送跳转到相关页面进行操作,JS交互时也需要跳转相关的页面,然后这个的页面都是不确定,每次跳转页面也不固定这时我们该怎么做呢?原文链接
简单思路:
1、后台提供json,信息包括:要生成的控制器名称、跳转到该控制器所需的参数值。
2、利用objective-c强大的runtime动态特性,通过NSClassFromString生成控制器对象。
3、利用objective-c强大的runtime动态特性,通过setValue设置控制器对象所需的参数值。
4、获取window的rootViewcontroller,然后实现界面跳转
实现:
首先我们先对NSObject实现一个Category类代码如下:
.h文件
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface NSObject (Skip)
//通过字典生成对象, 根据字典的className决定生成
+(id)objectWithDict:(NSDictionary*)dict;
//设置对象属性值
-(void)setPropertiesWithDict:(NSDictionary*)dict;
//获取对象属性名
- (NSMutableArray*)getProperties;
- (NSMutableArray*)getPropertiesWithClass:(Class)cls;
@end
.m文件
#import "NSObject+Skip.h"
@implementation NSObject (Skip)
/**
* 根据字典生成对象,目前只支持基本类型
* 根据字典的className决定生成
* @param dict 字典
*
* @return id
*/
+(id)objectWithDict:(NSDictionary*)dict
{
if (!dict || ![dict objectForKey:@"className"]) {
return nil;
}
Class class = NSClassFromString([dict objectForKey:@"className"]);
id object = [[class alloc]init];
[self setPropertiesWithDict:dict object:object];
return object;
}
/**
* 根据字段设置对象的属性,支持基础属性
*
* @param dict 字典
* @param object 要设置的对象
*/
-(void)setPropertiesWithDict:(NSDictionary*)dict object:(id)object
{
Class class;
if ([dict objectForKey:@"className"]) {
class = NSClassFromString([dict objectForKey:@"className"]);
}
else{
class = self.class;
}
NSArray *properties = [self getPropertiesWithClass:class];
for (NSString* key in properties) {
if (dict[key]) {
[object setValue:dict[key] forKey:key];
}
}
}
-(void)setPropertiesWithDict:(NSDictionary*)dict
{
[self setPropertiesWithDict:dict object:self];
}
/**
* 获取某个类的所有字段名
*
* @param cls 要获取的类class
*
* @return 返回一个数组
*/
- (NSMutableArray*)getPropertiesWithClass:(Class)cls
{
// 获取当前类的所有属性
unsigned int count;// 记录属性个数
objc_property_t *properties = class_copyPropertyList(cls, &count);
// 遍历
NSMutableArray *mArray = [NSMutableArray array];
for (int i = 0; i < count; i++) {
// objc_property_t 属性类型
objc_property_t property = properties[i];
// 获取属性的名称 C语言字符串
const char *cName = property_getName(property);
// 转换为Objective C 字符串
NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
[mArray addObject:name];
}
return mArray.copy;
}
- (NSMutableArray*)getProperties
{
return [self getPropertiesWithClass:self.class];
}
@end
接下来我们写一个跳转控制类SkipManager代码如下:
.h文件
@interface SkipManager : NSObject
//根据json数据 创建我们想要跳转的Controller并对参数进行赋值
+(UIViewController*)createViewControllerWithDict:(NSDictionary*)dict;
//实现跳转
+(UIViewController*)createViewControllerWithDictAndPush:(NSDictionary*)dict;
@end
.m文件
#import "SkipManager.h"
#import "NSObject+Skip.h"
@implementation SkipManager
/**
* 根据字典生成viewcontroller
*
* @param dict 字典
*
* @return UIViewController
*/
+(UIViewController*)createViewControllerWithDict:(NSDictionary*)dict{
//storyboard布局,记得在传进来的dict 加上'storyboard': 'Main'
if ([dict objectForKey:@"storyboard"]) {
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:[dict objectForKey:@"storyboard"] bundle:nil];
//记得在storyboard的Storyboard ID改成对应的className
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:dict[@"className"]];
[vc setPropertiesWithDict:dict];
return vc;
}else{//纯代码布局和Xib布局
UIViewController *vc = [NSObject objectWithDict:dict];
return vc;
}
}
/**
* 根据字典生成viewcontroller 并自行跳转到vc。
* 所在vc为navigation中则pop到根页并push。
* 所在vc为基本viewcontroller则直接present
*
* @param dict 字典
*/
+(UIViewController*)createViewControllerWithDictAndPush:(NSDictionary*)dict{
//获取跳转目标Controller
UIViewController *vc = [self createViewControllerWithDict:dict];
if (!vc) {
return nil;
}
//获取根控制器
UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
//root为tabbar
if ([rootVC isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabVC = (UITabBarController *)rootVC;
UIViewController *tabRootVC = tabVC.viewControllers[tabVC.selectedIndex];
//tabbar的root为navigation 使用navigation跳转 否则 使用present
if ([tabRootVC isKindOfClass:[UINavigationController class]]) {
[(UINavigationController *)tabRootVC pushViewController:vc animated:YES];
}else{
[tabRootVC presentViewController:vc animated:YES completion:nil];
}
}else if([rootVC isKindOfClass:[UINavigationController class]]){
//root为navigation 直接push
[(UINavigationController*)rootVC pushViewController:vc animated:YES];
}else{
//root为uiviewcontroller 直接present
[(UIViewController *)rootVC presentViewController:vc animated:YES completion:nil];
}
return rootVC;
}
@end
到这边就准备完成,只需要后台json数据就可以实现跳转。这里的UIViewController、UINavigationController、UITabBarController都可以换成项目中对应的基类Controller.
使用代码示例:
NSDictionary * dic = @{@"className":@"MessageWebVC",@"strName":@"ssssds",@"index":@"222",@"array":@[@{@"strName":@"¥"},@{@"index":@"666"}],@"dic":@{@"index":@"666"}};
[SkipManager createViewControllerWithDictAndPush:dic];
json格式:
{
className:"MessageWebVC" //目标类名
storybroad:"Main" //如果是storybroad布局的一定要带参数
strName:"ssss" //对应的参数,这边需要注意参数的类型要对应好
.....
}
完,如果喜欢请关注下,O(∩_∩)O谢谢啦