runtime萬能界面跳轉(zhuǎn)

在你的開發(fā)過程中,是否遇到過如下的需求:

在tableView類型的展示列表中,點擊每個cell中人物頭像都可以跳轉(zhuǎn)到人物詳情,可參見微博中的頭像,同理包括轉(zhuǎn)發(fā)、評論按鈕、各種鏈接及l(fā)inkcard。

跳轉(zhuǎn)到任意頁面

(1)產(chǎn)品要求,某個頁面的不同banner圖,點擊可以跳轉(zhuǎn)到任何一個頁面,可能是原生的頁面A、頁面B,或者是web頁C。

(2)在web頁面,可以跳轉(zhuǎn)到任何一個原生頁面。

(3)在遠程推送中跳轉(zhuǎn)到任意指定的頁面。

以上2種需求,我想大多數(shù)開發(fā)者都遇到過,并且可以實現(xiàn)這種功能。畢竟,這是比較基礎(chǔ)的功能。但是代碼未必那么優(yōu)雅。

一般處理辦法

針對 1:一般初學(xué)者會用target或者block等方法在tableView的代理方法拿到事件,并把要執(zhí)行的跳轉(zhuǎn)寫到controller里。功能是可以實現(xiàn)的,但問題是這種cell及相似的cell(布局有些變化,或者多幾個少幾個控件)一般出現(xiàn)在多個頁面。這樣的話相同的代碼就會出現(xiàn)在多個地方。就算把跳轉(zhuǎn)方法抽取出來寫成category,但是target或者block總是每個地方都要寫的。

針對 2:初級的方法是每個地方寫一坨判斷及跳轉(zhuǎn),高級一些是抽取出來寫在基類或者category。

優(yōu)雅的解決辦法(利用runtime)

利用runtime動態(tài)生成對象、屬性、方法這特性,我們可以先跟服務(wù)端商量好,定義跳轉(zhuǎn)規(guī)則,比如要跳轉(zhuǎn)到A控制器,需要傳屬性id、type,那么服務(wù)端返回字典給我,里面有控制器名,兩個屬性名跟屬性值,客戶端就可以根據(jù)控制器名生成對象,再用kvc給對象賦值,這樣就搞定了。

舉例:比如根據(jù)推送規(guī)則跳轉(zhuǎn)對應(yīng)界面HSFeedsViewController

HSFeedsViewController.h:

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

AppDelegate.m 中添加以下代碼片段:

推送過來的消息規(guī)則

// 這個規(guī)則肯定事先跟服務(wù)端溝通好,跳轉(zhuǎn)對應(yīng)的界面需要對應(yīng)的參數(shù)NSDictionary*userInfo = @{

@"class": @"HSFeedsViewController",

@"property": @{

@"ID": @"123",

@"type": @"12"}

};

接收推送消息

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo

{

? ? ?[selfpush:userInfo];

}

跳轉(zhuǎn)界面:

- (void)push:(NSDictionary*)params

{// 類名NSString*class =[NSStringstringWithFormat:@"%@", params[@"class"]];constchar*className = [class cStringUsingEncoding:NSASCIIStringEncoding];// 從一個字串返回一個類Class newClass = objc_getClass(className);if(!newClass)

{// 創(chuàng)建一個類Class superClass = [NSObjectclass];

newClass = objc_allocateClassPair(superClass, className,0);// 注冊你創(chuàng)建的這個類objc_registerClassPair(newClass);

}// 創(chuàng)建對象idinstance = [[newClass alloc] init];// 對該對象賦值屬性NSDictionary* propertys = params[@"property"];

[propertys enumerateKeysAndObjectsUsingBlock:^(idkey,idobj,BOOL*stop) {// 檢測這個對象是否存在該屬性if([selfcheckIsExistPropertyWithInstance:instance verifyPropertyName:key]) {// 利用kvc賦值[instance setValue:obj forKey:key];

}

}];// 獲取導(dǎo)航控制器UITabBarController*tabVC = (UITabBarController*)self.window.rootViewController;UINavigationController*pushClassStance = (UINavigationController*)tabVC.viewControllers[tabVC.selectedIndex];// 跳轉(zhuǎn)到對應(yīng)的控制器[pushClassStance pushViewController:instance animated:YES];

}

檢測對象是否存在該屬性:

- (BOOL)checkIsExistPropertyWithInstance:(id)instance verifyPropertyName:(NSString*)verifyPropertyName

{unsignedintoutCount, i;// 獲取對象里的屬性列表objc_property_t * properties = class_copyPropertyList([instance

class], &outCount);for(i =0; i < outCount; i++) {

objc_property_t property =properties[i];//? 屬性名轉(zhuǎn)成字符串NSString*propertyName = [[NSStringalloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];// 判斷該屬性是否存在if([propertyName isEqualToString:verifyPropertyName]) {

free(properties);returnYES;

}

}

free(properties);returnNO;

}

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,032評論 0 9
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,525評論 19 139
  • 九天之上 蒼穹之頂 云煙縹緲 仙峰沉浮 鶴鳴聲遙遙傳來 ,一只丹頂黑啄白翅的仙鶴風(fēng)馳電掣般飛過云層,細看那鶴身,隱...
    504金貝貝閱讀 1,206評論 0 0
  • 我一直都是一個不錯的助理!這個月在門診實習(xí)的日子,累并快樂著!對于一向不愛運動的我來說,這樣的勞動強度遠遠超過我的...
    竺子閱讀 372評論 0 0
  • 鰉魚島初步得到了當(dāng)?shù)鼐用竦恼J可,認為開發(fā)當(dāng)?shù)貚u嶼是趨勢,而且是民心所向,而且今天攀談的是一位在島上開小賣店的居民,...
    龍騰虎躍江一龍閱讀 246評論 0 1

友情鏈接更多精彩內(nèi)容