iOS狀態(tài)欄設(shè)置無效問題處理

在iOS應(yīng)用程序開發(fā)中,狀態(tài)欄是顯示在屏幕頂部的系統(tǒng)信息條,用于顯示信號(hào)、電量等重要信息。有時(shí)候我們需要對(duì)狀態(tài)欄顏色進(jìn)行自定義,但在實(shí)際開發(fā)中可能會(huì)遇到一些困難。

之前寫過iOS狀態(tài)欄如何設(shè)置的問題,見鏈接 iOS狀態(tài)欄設(shè)置 - 簡書 (jianshu.com)

我們用的方案是 控制器優(yōu)先控制狀態(tài)欄的展示,也就是默認(rèn)的,狀態(tài)欄的文字是黑色的。在需要更新狀態(tài)欄顏色的控制器返回需要的樣式,比如在視頻播放器頁面狀態(tài)欄文字返回白色。

問題描述

但是最近遇到了狀態(tài)欄不更新的問題。問題是這樣的,在使用模態(tài)方式(模態(tài)風(fēng)格是custom)彈出了帶導(dǎo)航欄的控制器后,使用該控制器,push 一個(gè)需要展示 白色文字 狀態(tài)欄的 視圖控制器,這個(gè)控制器關(guān)于狀態(tài)欄的方法一直未被調(diào)用,導(dǎo)致使用的還是黑色文字的狀態(tài)欄。

image.png

就是 圖中 這個(gè)導(dǎo)航 push 出來的頁面控制器 狀態(tài)欄相關(guān)的方法都沒有被調(diào)用。導(dǎo)致狀態(tài)欄沒有更新為預(yù)期的樣子。

問題分析

而不是這種present出來的導(dǎo)航push就沒有這個(gè)問題。更嚴(yán)格的說,模態(tài)方式是 UIModalPresentationFullScreen 這種方式 也是沒有問題的。但問題使用其他的方式 比如 UIModalPresentationCustom 或者 UIModalPresentationOverFullScreen 或者 UIModalPresentationOverCurrentContext 會(huì)有這個(gè)問題。這說明模態(tài)方式,也會(huì)影響狀態(tài)欄的設(shè)置。

而我們的業(yè)務(wù)需要這個(gè)present出來的頁面是半透明的,因此不能用UIModalPresentationFullScreen,只能用 UIModalPresentationCustom 或者 UIModalPresentationOverFullScreen,使用這種方式,狀態(tài)欄就是不能正確更新。

我們無法更改 UIModalPresentationStyle ,只能 想辦法 讓 我們viewController狀態(tài)欄相關(guān)的方法得到調(diào)用。

問題處理

第一步: 打通狀態(tài)欄樣式的傳遞鏈條

以視圖控制器優(yōu)先控制狀態(tài)欄的方式中,window的狀態(tài)管理器會(huì)層層詢問,如果問到了就不再詢問,比如會(huì)問window的root VC,狀態(tài)欄要展示什么,root VC 如果返回了就不再繼續(xù),通常 rootVC是個(gè)容器控制器,會(huì)詢問子控制器,一直問到結(jié)果位置,因此,要想 子控制的狀態(tài)欄相關(guān)的方法會(huì)被調(diào)用,這個(gè)鏈條得通。所以要對(duì) 容器做處理,實(shí)現(xiàn)狀態(tài)欄相關(guān)的詢問方法。

比如,對(duì)于Tabbar控制器,我們這么寫

- (UIViewController *)childViewControllerForStatusBarHidden {
    return self.selectedViewController;
}

- (UIViewController *)childViewControllerForStatusBarStyle {
    return self.selectedViewController;
}

對(duì)于導(dǎo)航控制器,我們這么寫

- (UIViewController *)childViewControllerForStatusBarHidden {
    return self.topViewController;
}

- (UIViewController *)childViewControllerForStatusBarStyle {
    return self.topViewController;
}

第二步: 模態(tài)時(shí)接管狀態(tài)欄的處理

通過第一步,我們保證了即便控制器被包括在容器中,也都有機(jī)會(huì)處理狀態(tài)欄。

然而,這么寫,仍然沒有解決我們的問題,我們的方法沒有被調(diào)用,因?yàn)閳D中那個(gè)導(dǎo)航控制器相關(guān)的詢問事件都沒有觸發(fā)。看似是系統(tǒng)導(dǎo)致的,我們很難找到原因,我們只知道模特的方法影響了狀態(tài)欄響應(yīng)鏈條的傳遞。

經(jīng)過仔細(xì)的分析,不停的試一試,我們終于找到了問題的關(guān)鍵。當(dāng)我們以模態(tài)方式出現(xiàn)時(shí),并且有些模態(tài)方式,控制器是拿不到狀態(tài)欄的掌控權(quán)的,其中有一個(gè)屬性就是用來做這個(gè)事情的。這個(gè)屬性就是 modalPresentationCapturesStatusBarAppearance該屬性的默認(rèn)值是NO,也就是說 以模態(tài)方式出現(xiàn)時(shí),默認(rèn)不 捕獲狀態(tài)欄的 處理。

然而,我們肯定是要接管狀態(tài)欄的處理的,因?yàn)楸仨殞⑦@個(gè)屬性設(shè)置為YES,可以通過復(fù)寫 也可以直接設(shè)置。

在我們的問題中,我們只需要復(fù)寫或者設(shè)置這個(gè)屬性,一定接管 狀態(tài)欄的處理,我們的問題就得到了解決。

- (BOOL)modalPresentationCapturesStatusBarAppearance {
    return YES;
}

通過以上兩個(gè)步驟,讓我們的應(yīng)用徹底掌握狀態(tài)欄的設(shè)置。

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

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

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