你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS 萬能跳轉界面方法 (runtime實用篇一)

iOS 萬能跳轉界面方法 (runtime實用篇一)

編輯:IOS開發基礎

nature-person-red-woman-large.jpg

作者:漢斯哈哈哈 授權本站轉載。

在開發項目中,會有這樣變態的需求:

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

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

思考:wocao!這變態的需求,要拒絕他嗎?

switch判斷呗,考慮所有跳轉的因素?這不得寫死我...

switch () {
    case :
        break;
    default:
        break;
}

我是這麼個實現的(runtime是個好東西)

利用runtime動態生成對象、屬性、方法這特性,我們可以先跟服務端商量好,定義跳轉規則,比如要跳轉到A控制器,需要傳屬性id、type,那麼服務端返回字典給我,裡面有控制器名,兩個屬性名跟屬性值,客戶端就可以根據控制器名生成對象,再用kvc給對象賦值,這樣就搞定了 ---O(∩_∩)O哈哈哈

比如:根據推送規則跳轉對應界面HSFeedsViewController

HSFeedsViewController.h:

  • 進入該界面需要傳的屬性

@interface HSFeedsViewController : UIViewController
// 注:根據下面的兩個屬性,可以從服務器獲取對應的頻道列表數據
/** 頻道ID */
@property (nonatomic, copy) NSString *ID;
/** 頻道type */
@property (nonatomic, copy) NSString *type;
@end

AppDelegate.m:

  • 推送過來的消息規則

// 這個規則肯定事先跟服務端溝通好,跳轉對應的界面需要對應的參數
NSDictionary *userInfo = @{
                           @"class": @"HSFeedsViewController",
                           @"property": @{
                                        @"ID": @"123",
                                        @"type": @"12"
                                   }
                           };
  • 接收推送消息

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [self push:userInfo];
}
  • 跳轉界面

- (void)push:(NSDictionary *)params
{
    // 類名
    NSString *class =[NSString stringWithFormat:@"%@", params[@"class"]];
    const char *className = [class cStringUsingEncoding:NSASCIIStringEncoding];
    // 從一個字串返回一個類
    Class newClass = objc_getClass(className);
    if (!newClass)
    {
        // 創建一個類
        Class superClass = [NSObject class];
        newClass = objc_allocateClassPair(superClass, className, 0);
        // 注冊你創建的這個類
        objc_registerClassPair(newClass);
    }
    // 創建對象
    id instance = [[newClass alloc] init];
    // 對該對象賦值屬性
    NSDictionary * propertys = params[@"property"];
    [propertys enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        // 檢測這個對象是否存在該屬性
        if ([self checkIsExistPropertyWithInstance:instance verifyPropertyName:key]) {
            // 利用kvc賦值
            [instance setValue:obj forKey:key];
        }
    }];
    // 獲取導航控制器
    UITabBarController *tabVC = (UITabBarController *)self.window.rootViewController;
    UINavigationController *pushClassStance = (UINavigationController *)tabVC.viewControllers[tabVC.selectedIndex];
    // 跳轉到對應的控制器
    [pushClassStance pushViewController:instance animated:YES];
}
  • 檢測對象是否存在該屬性

- (BOOL)checkIsExistPropertyWithInstance:(id)instance verifyPropertyName:(NSString *)verifyPropertyName
{
    unsigned int outCount, i;
    // 獲取對象裡的屬性列表
    objc_property_t * properties = class_copyPropertyList([instance
                                                           class], &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property =properties[i];
        //  屬性名轉成字符串
        NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
        // 判斷該屬性是否存在
        if ([propertyName isEqualToString:verifyPropertyName]) {
            free(properties);
            return YES;
        }
    }
    free(properties);
    return NO;
}

具體使用和代碼: https://github.com/HHuiHao/Universal-Jump-ViewController

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved