1.萬能跳轉(zhuǎn)的應(yīng)用場景:
(1)手機(jī)App通過推送過來的數(shù)據(jù)內(nèi)容來跳轉(zhuǎn)不同的界面合武,并把界面數(shù)據(jù)展示出來。
(2)手機(jī)內(nèi)部根據(jù)不同的cell的點(diǎn)擊事件度陆,不同的數(shù)據(jù)跳轉(zhuǎn)不同的界面亮蒋。
2.工作的流程圖:
通過動態(tài)返回的數(shù)據(jù)中的class類名副编,來去查詢class是不是存在:(1)存在則獲取實(shí)例對象然后通過kVC來綁定數(shù)據(jù)然后去跳轉(zhuǎn)负甸。(2)不存在則動態(tài)創(chuàng)建class及其變量,然后手動創(chuàng)建實(shí)例對象在通過KVC來綁定數(shù)據(jù)痹届,最后跳轉(zhuǎn)呻待。
3.主要方法:
//創(chuàng)建Class
objc_allocateClassPair(Class superclass, const char * name, size_t extraBytes)
//注冊Class
void objc_registerClassPair(Class cls)
//添加變量
class_addIvar(Class cls, const char * name,size_t size, uint8_t alignment , const char * types)
//添加方法
class_addMethod(Class cls, SEL name, IMP imp, const char * types)
//獲取屬性
class_getProperty(Class cls, const char * name)
//獲取實(shí)例變量
class_getInstanceVariable(Class cls, const char * name)
4.代碼實(shí)現(xiàn):
1、工程中新建三個(gè)控制器队腐,命名為
FirstViewController
SecondViewController
ThredViewController
每一個(gè)控制器的viewDidLoad
方法里面的內(nèi)容為
self.view.backgroundColor = [UIColor redColor];
UILabel * titleLab = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 200, 40)];
titleLab.textColor = [UIColor blackColor];
[self.view addSubview:titleLab];
titleLab.text =self.name;
然后在ViewController模擬根據(jù)不同數(shù)據(jù)跳轉(zhuǎn)不同界面蚕捉,代碼如下
#import "ViewController.h"
#import <objc/message.h>
@interface ViewController ()
@property (nonatomic, weak) UISegmentedControl * seg;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor yellowColor];
NSArray * array = @[@"消息1",@"消息2",@"消息3",@"消息4"];
UISegmentedControl * seg = [[UISegmentedControl alloc]initWithItems:array];
seg.frame = CGRectMake(70, 200, 240, 45);
[self.view addSubview:seg];
seg.selectedSegmentIndex = 0;
self.seg = seg;
UIButton * jupBtn = [UIButton buttonWithType:UIButtonTypeCustom];
jupBtn.frame = CGRectMake(100, 250, 60, 45);
[jupBtn setTitle:@"跳轉(zhuǎn)" forState:UIControlStateNormal];
[jupBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
jupBtn.backgroundColor = [UIColor redColor];
[self.view addSubview:jupBtn];
[jupBtn addTarget:self action:@selector(action) forControlEvents:UIControlEventTouchUpInside];
//創(chuàng)建Class
//objc_allocateClassPair(Class superclass, const char * name, size_t extraBytes)
//注冊Class
//void objc_registerClassPair(Class cls)
//添加變量
//class_addIvar(Class cls, const char * name,size_t size, uint8_t alignment , const char * types)
//添加方法
//class_addMethod(Class cls, SEL name, IMP imp, const char * types)
//獲取屬性
//class_getProperty(Class cls, const char * name)
//獲取實(shí)例變量
//class_getInstanceVariable(Class cls, const char * name)
}
-(void)action{
NSDictionary * infoDic = nil;
switch (self.seg.selectedSegmentIndex) {
case 0:
infoDic = @{@"class":@"FirstViewController",
@"property":@{
@"name":@"尼古拉斯趙四"
}
};
break;
case 1:
infoDic = @{@"class":@"SecondViewController",
@"property":@{
@"age":@"26",
@"sex":@"男"
}
};
break;
case 2:
infoDic = @{@"class":@"ThredViewController",
@"property":@{
@"teacher":@"王老師",
@"money":@"5000"
}
};
break;
case 3:
//NewViewController
infoDic = @{@"class":@"WorkerController",
@"property":@{
@"phoneNumber":@"17710948530"
}
};
break;
default:
break;
}
[self pushToControllerWithData:infoDic];
}
-(void)pushToControllerWithData:(NSDictionary * )vcData{
//1.獲取class
const char * className = [vcData[@"class"] UTF8String];
Class cls = objc_getClass(className);
if(!cls){
//創(chuàng)建新的類,并添加變量和方法
Class superClass = [UIViewController class];
cls = objc_allocateClassPair(superClass, className, 0);
//添加phoneNumber變量
class_addIvar(cls, "phoneNumber", sizeof(NSString *), log2(sizeof(NSString *)), @encode(NSString *));
//添加titleLab控件
class_addIvar(cls, "titleLab", sizeof(UILabel *), log2(sizeof(UILabel *)), @encode(UILabel *));
//添加方法柴淘,方法交換迫淹,執(zhí)行viewDidLoad加載
Method method = class_getInstanceMethod([self class], @selector(workerLoad));
IMP methodIMP = method_getImplementation(method);
const char * types = method_getTypeEncoding(method);
class_addMethod(cls, @selector(viewDidLoad), methodIMP, types);
}
//2.創(chuàng)建實(shí)例對象,給屬性賦值
id instance = [[cls alloc]init];
NSDictionary * values = vcData[@"property"];
[values enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
//檢測是否存在為key的屬性
if(class_getProperty(cls, [key UTF8String])){
[instance setValue:obj forKey:key];
}
//檢測是否存在為key的變量
else if (class_getInstanceVariable(cls, [key UTF8String])){
[instance setValue:obj forKey:key];
}
}];
//2.跳轉(zhuǎn)到對應(yīng)的界面
[self.navigationController pushViewController:instance animated:YES];
}
-(void)workerLoad{
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
//初始化titleLab
[self setValue:[[UILabel alloc]initWithFrame:CGRectMake(100, 100, 200, 40)] forKey:@"titleLab"];
UILabel * titleLab = [self valueForKey:@"titleLab"];
//添加到視圖上
[[self valueForKey:@"view"] performSelector:@selector(addSubview:) withObject:titleLab];
titleLab.text =[self valueForKey:@"phoneNumber"];
titleLab.textColor = [UIColor blackColor];
}
@end
5.demo的下載地址为严,喜歡的話給個(gè)星敛熬,謝謝:
iOS根據(jù)不同數(shù)據(jù)跳轉(zhuǎn)不同界面,動態(tài)添加屬性及其控件等界面內(nèi)容