通常由一个controller跳转到下一页面做法是:
#import "ViewController.h"
#import "WGOneViewController.h"
从ViewController跳转到WGOneViewController
WGOneViewController *con = [[WGOneViewController alloc] init];
[self.navigationController pushViewController:con animated:YES];
当然项目前期这么做也没有什么不对,但是会存在一个问题:当项目越来越大或者从ViewController跳转的下一页面越来越多的时候,就需要导入很多的头文件,造成多个页面的相互依赖,在项目后期需要组件化或者特定需求的时候就会造成很大困难。
这里给出一种不需要导入头文件的方案,这是demo
总体思路我根据代码详细给出:
- 新建一个页面的管理类,在里面统一管理需要跳转的类名称,即:每一个类名对应一个唯一ID,例如@”1-2“。这个id可以根据项目自己定义,我这里@"1-2"中1代表tabbar的索引,2代表在这个索引下的一个。
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface WGControllerId : NSObject
//单例
+ (WGControllerId *)WGControllerIdShare;
//根据页面id获取类名
- (NSString *)getControolerName:(NSString *)pageId;
//进行页面跳转的接口,fromCon是从哪个页面开始跳,toPageId是将要跳转到的页面id,isHas代表是否需要传值 ,param是需要传的值
- (void)pushFromController:(UIViewController *)fromCon toPageId:(NSString *)pageId hasParam:(BOOL)isHas param:(NSDictionary *)param;
@end
/*
页面跳转的类统一在这里管理,key唯一,例如@"1-2"中1可代表tabbar中第1个
*/
- (NSString *)getControolerName:(NSString *)pageId{
NSDictionary *pageDic = @{@"1-1":@"WGOneViewController",
@"1-2":@"WGTwoViewController",
@"1-3":@"WGThreeViewController"
};
return [pageDic valueForKey:pageId];
}
- 页面管理类负责跳转接口实现:
这里在属性传值的时候我自己定义了一个传值规则:在param这个字典中每一个key是需要属性传值的属性名,例如WGTwoViewController.h中有一个titleStr属性需要传值,那么我的传值字典内容为@{@"titleStr":@"这是需要传的值"}
这么做的目的就是在真正跳转的方法里,我只需要根据字典中的key就可以通过Runtime来生成对应属性的set方法,通过msg_send来把值传给下一页。
当然如果有更好的方法,也麻烦告诉我,非常感谢😊😊
- (void)pushFromController:(UIViewController *)fromCon toPageId:(NSString *)pageId hasParam:(BOOL)isHas param:(NSDictionary *)param{
//根据定义好的pageId,拿到类名字符串
NSString *className = [self getControolerName:pageId];
//根据类名转化为Class类型
Class classCon = NSClassFromString(className);
//初始化并分配内存
id toCon = [[classCon alloc] init];
if (isHas) {
//需要属性传值,则通过运行时来解决
NSArray *keyArr = [param allKeys];
for (int i = 0; i<keyArr.count; i++) {
NSString *key = [keyArr objectAtIndex:i];
id value = [param valueForKey:key];
//把key的首字母大写
NSString *firstStr = [key substringWithRange:NSMakeRange(0, 1)].uppercaseString;
NSString *restStr = [key substringFromIndex:1];
//生成对应属性的set方法
NSString *selName = [NSString stringWithFormat:@"set%@%@:", firstStr, restStr];
SEL method = NSSelectorFromString(selName);
if ([toCon respondsToSelector:method]) {
//等价于controller.shuxing = value;
objc_msgSend(toCon, method, value);
}
}
}
[fromCon.navigationController pushViewController:toCon animated:YES];
}
- 在我的demo中进行页面跳转ViewController类里
switch (row) {
case 0:{
[[WGControllerId WGControllerIdShare] pushFromController:self toPageId:self.dataArr[row] hasParam:NO param:nil];
break;
}
case 1:{
[[WGControllerId WGControllerIdShare] pushFromController:self toPageId:self.dataArr[row] hasParam:YES param:@{@"titleStr":@"标题是传过来的"}];
break;
}
case 2:{
[[WGControllerId WGControllerIdShare] pushFromController:self toPageId:self.dataArr[row] hasParam:YES param:@{@"name":@"名字叫wg", @"age":@18}];
break;
}
#import "ViewController.h"
#import "WGControllerId.h"
这样我就不需要在ViewController里引入头文件了。如果对runtime不是很熟悉或者对生成属性的set方法那里不太明白的话可看我的这篇文章。
网友评论