ios萬能跳轉介面方法(Runtime)

一個蘿蔔壹個坑發表於2018-01-03

在開發專案中,會有這樣變態的需求:

•推送:根據服務端推送過來的資料規則,跳轉到對應的控制器

•列表:不同類似的名字,可能跳轉不同的控制器(噓!產品經理是這樣要求:我也不確定會跳轉哪個介面哦,可能是這個又可能是那個,能給我做靈活嗎?根據後臺返回規則任意跳轉?)

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

相關文章