在開發專案中,會有這樣變態的需求:
•推送:根據服務端推送過來的資料規則,跳轉到對應的控制器
•列表:不同類似的名字,可能跳轉不同的控制器(噓!產品經理是這樣要求:我也不確定會跳轉哪個介面哦,可能是這個又可能是那個,能給我做靈活嗎?根據後臺返回規則任意跳轉?)
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;
}
參考部落格:
http://www.cocoachina.com/ios/20150824/13104.html
http://blog.csdn.net/sike2008/article/details/50164961