UITabBarController的selectedIndex不走delegate和kvo

摘要:runtime、kvo氨距、selectedIndex

在開發(fā)公司的一個(gè)項(xiàng)目時(shí)桑逝,遇到一個(gè)說正常也正常,說奇葩也奇葩的需求俏让,需求如下:1楞遏、首頁tab有好幾個(gè)其他tab的入口茬暇,點(diǎn)擊該入口進(jìn)入指定的tab(比如“秘籍"Tab)

2、進(jìn)入“秘籍”tab需要先登錄才能進(jìn)入使用寡喝,

2.1而钞、如果用戶已經(jīng)登錄,直接進(jìn)入“秘籍”tab使用相關(guān)功能

2.2拘荡、如果當(dāng)用戶未登錄時(shí)臼节,是需要先到“秘籍”tab所在頁面顯示空白提示信息,比如“您還未登錄珊皿,請(qǐng)先登錄”网缝,然后展示登錄頁面

2.2.1、如果正常登錄或注冊(cè)成功蟋定,顯示“秘籍”tab功能

2.2.2粉臊、如果用戶在登錄頁面沒有登錄,點(diǎn)擊了登錄頁面的返回按鈕驶兜,則要返回到“秘籍”之前的那個(gè)tab里扼仲,比如如果從首頁的某個(gè)按鈕進(jìn)入“秘籍”tab,則返回首頁抄淑,如果從“我的”tab點(diǎn)擊底部的tab按鈕就如“秘籍”tab屠凶,則回到“我的”tab

剛拿到這個(gè)需求時(shí)想著直接寫個(gè)自定義的UITabBarController,然后設(shè)置代理肆资,在shouldSelectViewController:和didSelectViewController:做下記錄進(jìn)入“秘籍”tab之前的tab矗愧,然后當(dāng)點(diǎn)擊登錄頁面返回按鈕時(shí)直接選中記錄的tab就可以了,但在實(shí)際的代碼里卻發(fā)現(xiàn)當(dāng)從首頁的按鈕入口進(jìn)入“秘籍”tab時(shí)郑原,使用的是tabVC.selectedIndex=xx,這種方式并不會(huì)走UITabBarController的代理回調(diào)唉韭,為了解決這個(gè)辦法,我寫了一個(gè)UITabBarController的分類犯犁,使用runtime修改了setSelectIndex:這個(gè)方法,然后為了方便起見属愤,也放棄了在shouldSelectViewController:和didSelectViewController:中操作的方式,因?yàn)樵摲椒梢酝瑫r(shí)讓我拿到old和new兩個(gè)tab對(duì)應(yīng)的內(nèi)容酸役,而使用kvo監(jiān)聽selectedViewController的變化住诸,但kvo也面臨使用setSelectIndex收不到通知的問題,解決辦法是在這個(gè)分類里手動(dòng)發(fā)送kvo的變化簇捍,具體分類代碼如下:

// ZQQTabBarController.h

@interface ZQQTabBarController :UITabBarController

@end

// ZQQTabBarController.m

@implementation ZQQTabBarController

- (void)viewDidLoad {

[self addObserver:selfforKeyPath:@"selectedViewController"options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOldcontext:nil];

}

- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context{

if([keyPathisEqualToString:@"selectedViewController"]) {

   if(nil != change[@"old"]) {//記錄前一個(gè)tab}

   }

}

// UITabBarController+ZQQTabBarController.h

@interface UITabBarController (ZQQTabBarController)

@end

// UITabBarController+ZQQTabBarController.m

@implementation UITabBarController (ZQQTabBarController)

+ (void)load

{

MethodoriginalMethod =class_getInstanceMethod(self,@selector(setSelectedIndex:));

MethodswizzledMethod =class_getInstanceMethod(self,@selector(zqq_setSelectedIndex:));

method_exchangeImplementations(originalMethod, swizzledMethod);

}

- (void)zqq_setSelectedIndex:(NSInteger)index

{

if(index >=self.childViewControllers.count|| index <0) {

return;

}

if(self.delegate==nil) {//如果沒有代理只壳,直接調(diào)用修改index的方法

[self willChangeValueForKey:@"selectedViewController"];

[self zqq_setSelectedIndex:index];

[self didChangeValueForKey:@"selectedViewController"];

}else{

//即將被選中的controller

UIViewController *willBeSelectController =self.childViewControllers[index];

//如果可以被選中,則繼續(xù)下一步操作

if([self zqq_canSelectController:willBeSelectController]) {

//手動(dòng)發(fā)送節(jié)將修改通知

[self willChangeValueForKey:@"selectedViewController"];

//修改index

[self zqq_setSelectedIndex:index];

//如果delegate實(shí)現(xiàn)了這個(gè)代理方法暑塑,調(diào)用該代理方法

if([self.delegate respondsToSelector:@selector(tabBarController:didSelectViewController:)]) {

[self.delegate tabBarController:selfdidSelectViewController:willBeSelectController];

}

//發(fā)送已經(jīng)修改內(nèi)容通知

[self didChangeValueForKey:@"selectedViewController"];

}

}

}

/**

判斷即將被選中的controller是否可以被選中

@paramwillBeSelectController即將被選中的controller

@return是否可以被選中

*/

- (BOOL)zqq_canSelectController:(UIViewController*)willBeSelectController

{

//如果delegate實(shí)現(xiàn)了判斷是否可選中的方法吼句,用代理的方法判斷

if([self.delegate respondsToSelector:@selector(tabBarController:shouldSelectViewController:)]) {

return[self.delegate tabBarController:selfshouldSelectViewController:willBeSelectController];

}else{

//如果delegate沒有實(shí)現(xiàn)是否允許選中controller的方法,則默認(rèn)為可以選中

returnYES;

}

}
@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末事格,一起剝皮案震驚了整個(gè)濱河市惕艳,隨后出現(xiàn)的幾起案子搞隐,更是在濱河造成了極大的恐慌,老刑警劉巖远搪,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劣纲,死亡現(xiàn)場離奇詭異,居然都是意外死亡谁鳍,警方通過查閱死者的電腦和手機(jī)癞季,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倘潜,“玉大人绷柒,你說我怎么就攤上這事′桃颍” “怎么了废睦?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長养泡。 經(jīng)常有香客問我嗜湃,道長,這世上最難降的妖魔是什么澜掩? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任购披,我火速辦了婚禮,結(jié)果婚禮上输硝,老公的妹妹穿的比我還像新娘今瀑。我一直安慰自己程梦,他們只是感情好点把,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屿附,像睡著了一般郎逃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挺份,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天褒翰,我揣著相機(jī)與錄音,去河邊找鬼匀泊。 笑死优训,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的各聘。 我是一名探鬼主播揣非,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼躲因!你這毒婦竟也來了早敬?” 一聲冷哼從身側(cè)響起忌傻,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搞监,沒想到半個(gè)月后水孩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡琐驴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年俘种,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绝淡。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡安疗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出够委,到底是詐尸還是另有隱情荐类,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布茁帽,位于F島的核電站玉罐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏潘拨。R本人自食惡果不足惜吊输,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望铁追。 院中可真熱鬧季蚂,春花似錦、人聲如沸琅束。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涩禀。三九已至料滥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間艾船,已是汗流浹背葵腹。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屿岂,地道東北人践宴。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像爷怀,于是被迫代替她去往敵國和親阻肩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容