iOS - APP任意push新頁面那些事

大家都知道,UINavigationController對(duì)象有一個(gè)方法pushViewController,用來做視圖跳轉(zhuǎn),也是在iOS開發(fā)中常用的頁面轉(zhuǎn)換方法之一。大多數(shù)APP的結(jié)構(gòu)一般都是,使用一個(gè)UITabBarController,每個(gè)tab上都是一個(gè)UINavigationController,然后各個(gè)tab上的navigationController自己管理各自的視圖棧。

Paste_Image.png

這個(gè)時(shí)候,如果此時(shí)APP想要push一個(gè)新的VC,一般是在某個(gè)VC上調(diào)用:

[self.navigationController pushViewController:newVC animated:YES];

那問題來了,產(chǎn)品比較任性,如果有一個(gè)需求,就是要求做一個(gè)跳轉(zhuǎn)工具,要求要能在任何地方(包括非VC中),都能在當(dāng)前頁面push新的VC,那又該怎么做呢?

Paste_Image.png

如果能拿到UITabBarController的對(duì)象,例如放在了delegate中(這里設(shè)想AppDelegateInstance就是delegate的對(duì)象,而UITabBarController的成員變量名為tabBar),也可以使用

[AppDelegateInstance.tabBar.selectedViewController pushViewController:newVC animated:YES];

好像能隨時(shí)push新VC了......
不對(duì)!狀況又來了,如果在當(dāng)前VC上可能又present出一個(gè)頁面,即present出一個(gè)新的NAV,這時(shí)候:

Paste_Image.png

這個(gè)時(shí)候,有可能AppDelegateInstance.tabBar.selectedViewController就不是當(dāng)前的NAV了,自然就不能正確push了。
那怎么辦呢?

Paste_Image.png

如果能拿到當(dāng)前正在顯示的NAV就好辦多了,那樣我直接拿這個(gè)NAV就可以push任何頁面了。
思路:
1.當(dāng)前顯示的肯定有一個(gè)window包含了所有視圖控制器、導(dǎo)航控制器;
2.視圖控制器、導(dǎo)航控制器出現(xiàn)的方式只有3中:tabBar selected、push、present;
3.從“1”的window出發(fā),找到每一層顯示中的NAV或者VC,直到找到最后一層,就是當(dāng)前顯示的VC,就能拿到當(dāng)前的NAV了。

這里我創(chuàng)建了一個(gè)分類UIApplication+Visible,獲取APP的主window,再遞歸進(jìn)行當(dāng)前顯示中VC、NAV的查詢:

#import "UIApplication+Visible.h"

@implementation UIApplication (Visible)

- (UIWindow *)mainWindow {
    return self.delegate.window;
}

- (UIViewController *)visibleViewController {
    UIViewController *rootViewController = [self.mainWindow rootViewController];
    return [self getVisibleViewControllerFrom:rootViewController];
}

- (UIViewController *) getVisibleViewControllerFrom:(UIViewController *) vc {
    if ([vc isKindOfClass:[UINavigationController class]]) {
        return [self getVisibleViewControllerFrom:[((UINavigationController *) vc) visibleViewController]];
    } else if ([vc isKindOfClass:[UITabBarController class]]) {
        return [self getVisibleViewControllerFrom:[((UITabBarController *) vc) selectedViewController]];
    } else {
        if (vc.presentedViewController) {
            return [self getVisibleViewControllerFrom:vc.presentedViewController];
        } else {
            return vc;
        }
    }
    
}

- (UINavigationController *)visibleNavigationController {
    return [[self visibleViewController] navigationController];
}
@end

然后你就這樣調(diào)用

UINavigationController *nav = [[UIApplication sharedApplication] visibleNavigationController];
[nav pushViewController:newVC animated:YES];

成功啦?。?!

Paste_Image.png

最后,可能有些人要疑惑,為什么mainWindow方法中要使用delegate.window而不使用[UIApplication sharedApplication].keyWindow呢?
因?yàn)閗eyWindow并不是一直都是APP的主界面的window,例如使用了UIAlertView,keyWindow就會(huì)變成alertView的window,這時(shí)候我們的輪子就不能跑了。

好了,可能有些地方寫得比較模糊、或者有缺陷,歡迎指出。

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

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,383評(píng)論 4 61
  • 1.自定義控件 a.繼承某個(gè)控件 b.重寫initWithFrame方法可以設(shè)置一些它的屬性 c.在layouts...
    圍繞的城閱讀 3,704評(píng)論 2 4
  • 我是個(gè)性格比較急躁的人,如果說是我正在忙其他事情,你問我這個(gè)事情怎么弄。我一般就會(huì)特別煩,所以我的脾氣不是特別好的...
    123小屁孩闖天下閱讀 344評(píng)論 0 0
  • 才剛剛離開家,在火車上過了一夜,現(xiàn)在就如此的想家,甚至鼻子都酸了。一直覺得自己小時(shí)候是很感性的,動(dòng)不動(dòng)就哭,后來,...
    城南少東家閱讀 292評(píng)論 0 1

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