當(dāng)我們的APP正在使用的時(shí)候,突然有電話打入、開啟熱點(diǎn)、語音接入、錄音開啟等情況下,會(huì)出現(xiàn),狀態(tài)欄高度改變,界面下移的情況。如果我們沒有做相關(guān)適配,那么有些界面會(huì)出現(xiàn)底部按鈕遮擋、界面下移導(dǎo)致的部分?jǐn)?shù)據(jù)遮擋等等情況。為了處理這種問題,下面提供一種解決思路,如有更好解決方案,萬望指教。
UIApplicationWillChangeStatusBarFrameNotification
這個(gè)通知,是監(jiān)聽狀態(tài)欄改變的通知。通過該通知,可以獲得狀態(tài)欄改變的rect值。
知道了這些,我們就有了一個(gè)大致的方向。那么接下來就是如何方便快捷地解決界面下移導(dǎo)致的問題了。
如果項(xiàng)目開始前,我們就把這個(gè)情況考慮進(jìn)去,那么最好的方案應(yīng)該是,先寫一個(gè)基類,然后把要做的操作盡量多的放入這個(gè)基類當(dāng)中。
如果項(xiàng)目已經(jīng)成形,相信你的VC也是有繼承基類的吧。如果沒有,你先去哭會(huì)吧??尥炅?,可以開始加班了。還是去創(chuàng)建一個(gè)基類,然后一個(gè)一個(gè)的去使你的VC繼承于他。即使你創(chuàng)建的這個(gè)基類現(xiàn)在只有這個(gè)解決界面下移的一個(gè)功能,以后也是有用的。好,不廢話。
先說下主體思路,然后開始詳細(xì)解釋:
1.通過UIApplicationWillChangeStatusBarFrameNotification通知方法可以監(jiān)聽到狀態(tài)欄的改變,并做處理。(其實(shí)我只是打印了狀態(tài)欄的改變情況,并未在此處做什么處理。如果你有什么好的方法可以在這里統(tǒng)一處理,萬望指點(diǎn)哪!)
2.由于項(xiàng)目中大量使用宏定義的屏幕高度導(dǎo)致替換不便。那么在需要的子控制器中添加方法 viewDidLayoutSubviews,就很有必要了:(-(void)viewDidLayoutSubviews//在某個(gè)類的內(nèi)部調(diào)整子視圖位置時(shí),就會(huì)調(diào)用)。在該方法中,去修改要修改的控件的frame;
具體如下:
一:在BaseViewController中,監(jiān)聽并處理。(點(diǎn)擊查看)
1.viewDidload中添加監(jiān)聽,如下:
/*
??此處用的是 WillChange ,將要改變的狀態(tài)監(jiān)聽。
*/
//監(jiān)聽狀態(tài)欄改變的通知 UIApplicationWillChangeStatusBarFrameNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(layoutControllerSubViews:)
name:UIApplicationWillChangeStatusBarFrameNotification object:nil];
2.#pragma mark ===== 狀態(tài)欄改變的通知 =====
-(void)layoutControllerSubViews:(NSNotification *)notification
{
NSValue *statusBarFrameValue =
[notification.userInfo valueForKey:UIApplicationStatusBarFrameUserInfoKey];
NSLog(@"statusBarFrameValue ===== %@",statusBarFrameValue);
//
CGRect rect;
[statusBarFrameValue getValue:&rect];
NSLog(@"statusBarFrameValue ===== %@,rect.Height === %f,self.view.height === %f",statusBarFrameValue,rect.size.height,self.view.frame.size.height);
/*
因?yàn)槭?WillChange,你會(huì)發(fā)現(xiàn),self.view.height 會(huì)是改變前的。多比較打印和界面,就可以明白了。
*/
}
這里你會(huì)發(fā)現(xiàn),self.view.frame.size.height的值是會(huì)跟隨狀態(tài)欄的改變而改變的。
二:通過viewDidLayoutSubviews方法修改需要處理的控件的frame。(點(diǎn)擊查看)
#pragma mark ===== viewDidLayoutSubviews =====
-(void)viewDidLayoutSubviews//在某個(gè)類的內(nèi)部調(diào)整子視圖位置時(shí),就會(huì)調(diào)用
{
//刷新頁面布局情況,解決打電話、開熱點(diǎn)等,導(dǎo)致的狀態(tài)欄高度改變引起界面下移情況
//1.刷新當(dāng)前VC中tableview的布局
CGFloat h = self.tabBarController.tabBar.frame.size.height;
_tableView.frame = CGRectMake(0, SafeAreaTopHeight, SCREEN_WIDTH, self.view.frame.size.height - SafeAreaTopHeight - SafeAreaBottomHeight - - h - _footerView.frame.size.height);
//2.刷新footerView的布局
CGFloat tabBarH = self.tabBarController.tabBar.frame.size.height;
[UIView animateWithDuration:0.4 animations:^{
_footerView.frame = CGRectMake(10, self.view.frame.size.height - tabBarH - 55, SCREEN_WIDTH - 20, 50);
}];
}
IPhoneX 的情況不考慮。為什么?自己測(cè)試下看看吧,這個(gè)機(jī)型狀態(tài)欄高度不變化。
Demo