冬至已到,圣誕將近,最近公司項(xiàng)目實(shí)在太多,三四個(gè)項(xiàng)目反復(fù)的切換真的讓人焦頭爛額,趁今天有點(diǎn)空,把維護(hù)的三個(gè)項(xiàng)目順利送出,剛好可以縷縷思路,記錄一下最近遇到的問(wèn)題。說(shuō)不著急那是假的,客戶(hù)一天天的催的確實(shí)令人心煩意亂,但是回過(guò)頭來(lái)想想也確實(shí)不易,所以還是說(shuō)服自己認(rèn)真對(duì)待他們反饋的一個(gè)個(gè)問(wèn)題,盡量做到讓他們滿(mǎn)意也讓自己滿(mǎn)意。有句話怎么說(shuō)來(lái),終于完成了,還好我沒(méi)放棄。哈哈,閑言不多講,說(shuō)一下最近遇到解決的一個(gè)問(wèn)題吧,由熱點(diǎn)引起狀態(tài)欄位置變化而導(dǎo)致自定義底部欄位置錯(cuò)位的問(wèn)題。
關(guān)于熱點(diǎn)的帖子網(wǎng)上確實(shí)不少,也給了很多的解決的方案。iPhone作為個(gè)人熱點(diǎn)且有連接時(shí),系統(tǒng)狀態(tài)欄下面會(huì)多一行熱點(diǎn)連接提示欄"Personal Hotspot: * Connection",縱向會(huì)下壓20pt;當(dāng)所有連接都斷開(kāi)時(shí),熱點(diǎn)欄消失,縱向高度恢復(fù)正常。
1.系統(tǒng)狀態(tài)欄
APP_STATUSBAR_HEIGHT=[UIApplication sharedApplication].statusBarFrame.size.height,包含熱點(diǎn)欄(如有)高度,標(biāo)準(zhǔn)高度為20pt,當(dāng)有個(gè)人熱點(diǎn)連接時(shí),高度為40pt。
// iOS系統(tǒng)版本
define SYSTEM_VERSION [[[UIDevice currentDevice] systemVersion] doubleValue]
// 標(biāo)準(zhǔn)系統(tǒng)狀態(tài)欄高度
define SYS_STATUSBAR_HEIGHT 20// 熱點(diǎn)欄高度#define HOTSPOT_STATUSBAR_HEIGHT 20// 導(dǎo)航欄(UINavigationController.UINavigationBar)高度#define NAVIGATIONBAR_HEIGHT 44// 工具欄(UINavigationController.UIToolbar)高度#define TOOLBAR_HEIGHT 44// 標(biāo)簽欄(UITabBarController.UITabBar)高度#define TABBAR_HEIGHT 44// APP_STATUSBAR_HEIGHT=SYS_STATUSBAR_HEIGHT+[HOTSPOT_STATUSBAR_HEIGHT]#define APP_STATUSBAR_HEIGHT (CGRectGetHeight([UIApplication sharedApplication].statusBarFrame))// 根據(jù)APP_STATUSBAR_HEIGHT判斷是否存在熱點(diǎn)欄#define IS_HOTSPOT_CONNECTED (APP_STATUSBAR_HEIGHT==(SYS_STATUSBAR_HEIGHT+HOTSPOT_STATUSBAR_HEIGHT)?YES:NO)// 無(wú)熱點(diǎn)欄時(shí),標(biāo)準(zhǔn)系統(tǒng)狀態(tài)欄高度+導(dǎo)航欄高度#define **NORMAL_STATUS_AND_NAV_BAR_HEIGHT **(SYS_STATUSBAR_HEIGHT+NAVIGATIONBAR_HEIGHT)// 實(shí)時(shí)系統(tǒng)狀態(tài)欄高度+導(dǎo)航欄高度,如有熱點(diǎn)欄,其高度包含在APP_STATUSBAR_HEIGHT中。#define STATUS_AND_NAV_BAR_HEIGHT (APP_STATUSBAR_HEIGHT+NAVIGATIONBAR_HEIGHT)
2.UIViewController.view.bounds.height
SYSTEM_VERSION < 7.0,UIViewController.view.bounds.height包含導(dǎo)航欄高度,不包含系統(tǒng)狀態(tài)欄高度,也不包含熱點(diǎn)欄(如果有)。
SYSTEM_VERSION ≥ 7.0,UIViewController.view.bounds.height包含標(biāo)準(zhǔn)系統(tǒng)狀態(tài)欄高度和導(dǎo)航欄高度,但不包含熱點(diǎn)欄(如果有)。
也即當(dāng)有熱點(diǎn)欄時(shí),UIViewController.view.bounds.height都自動(dòng)扣除了熱點(diǎn)欄的高度,iOS<7.0不包含標(biāo)準(zhǔn)系統(tǒng)狀態(tài)欄,iOS≥7.0包含標(biāo)準(zhǔn)系統(tǒng)狀態(tài)欄。由于iOS7把整個(gè)屏幕高度(包括狀態(tài)欄,不包括熱點(diǎn)欄)都作為了視圖控制器的有效高度,因此從iOS6升級(jí)到iOS7時(shí),會(huì)出現(xiàn)視圖整體上移了一個(gè)狀態(tài)欄的高度(20pt),并和上層的狀態(tài)欄交疊在一起。
上面的這兩段是借用的他們總結(jié)的一些說(shuō)明性的東西,分析的還很詳細(xì),原理還是要懂得,以后遇到問(wèn)題一定要學(xué)會(huì)總結(jié),不然的話太容易遺忘。網(wǎng)上給了一些解決的思路,我參考了比較好的兩篇博客,他們給的思路還是挺好的,但是還需要加一些處理和判斷,下面我說(shuō)一下解決問(wèn)題的完整過(guò)程吧。正常來(lái)說(shuō)熱點(diǎn)引起的狀態(tài)欄位置的調(diào)整有兩種情況,一個(gè)是當(dāng)前頁(yè)面已經(jīng)創(chuàng)建打開(kāi),另一個(gè)情況是頁(yè)面尚未創(chuàng)建,下面來(lái)專(zhuān)門(mén)區(qū)分一下。
1、狀態(tài)欄變化通知的處理和添加UIApplicationWillChangeStatusBarFrameNotification,
*UIApplicationDidChangeStatusBarFrameNotification是狀態(tài)欄變化會(huì)走的兩個(gè)通知,可以在
-
(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController.navigationBar setHidden:YES];[[ NSNotificationCenter defaultCenter ] addObserver : self selector : @selector (statusBarFrameWillChange:) name : UIApplicationWillChangeStatusBarFrameNotification object : nil ];
[[ NSNotificationCenter defaultCenter ] addObserver : self selector : @selector (layoutControllerSubViews:) name : UIApplicationDidChangeStatusBarFrameNotification object : nil ];
CGRect statusBarRect = [[UIApplication sharedApplication] statusBarFrame];
if (statusBarRect.size.height == 40)
{
[mytable setFrame:CGRectMake(0, -20, 320, UI_View_Hieght+64-58)];
[bottomView setFrame:CGRectMake(0,UI_View_Hieght+64-58-20,320, 58)];
}
else
{
[mytable setFrame:CGRectMake(0, 0, 320, UI_View_Hieght+64-58)];
[bottomView setFrame:CGRectMake(0,UI_View_Hieght+64-58,320, 58)];
}
}
經(jīng)過(guò)反復(fù)的測(cè)試發(fā)現(xiàn),原來(lái)通知只會(huì)在頁(yè)面已經(jīng)創(chuàng)建打開(kāi)這種情況下走,所以需要注冊(cè)監(jiān)聽(tīng)狀態(tài)欄的通知,并作處理
pragma mark-狀態(tài)欄錄音或通話狀態(tài)通知
-(void)layoutControllerSubViews:(NSNotification *)notification
{
//[UIApplication sharedApplication].statusBarFrame.size.height=20;
CGRect statusBarRect = [[UIApplication sharedApplication] statusBarFrame];
if (statusBarRect.size.height == 40)
{
[mytable setFrame:CGRectMake(0, -20, 320, UI_View_Hieght+64-58)];
[bottomView setFrame:CGRectMake(0,UI_View_Hieght+64-58-20,320, 58)];
}
else
{
[mytable setFrame:CGRectMake(0, 0, 320, UI_View_Hieght+64-58)];
[bottomView setFrame:CGRectMake(0,UI_View_Hieght+64-58,320, 58)];
}
}
-
(void)statusBarFrameWillChange:(NSNotification*)notification
{
//[self hideTabbar:self.statusBarHidden animated:YES];//[[UIApplication sharedApplication] setStatusBarHidden:YES];
CGRect statusBarRect = [[UIApplication sharedApplication] statusBarFrame];if (statusBarRect.size.height == 40)
{
[mytable setFrame:CGRectMake(0, -20, 320, UI_View_Hieght+64-58)];[bottomView setFrame:CGRectMake(0,UI_View_Hieght+64-58-20,320, 58)];}
else
{
[mytable setFrame:CGRectMake(0, 0, 320, UI_View_Hieght+64-58)];[bottomView setFrame:CGRectMake(0,UI_View_Hieght+64-58,320, 58)];}
}
另一種情況就是頁(yè)面尚未打開(kāi)前,熱點(diǎn)已經(jīng)連接,這樣的話打開(kāi)頁(yè)面是不會(huì)走通知的地方,需要在
- (void)viewWillAppear:(BOOL)animated 加上上面的處理,和通知里面的代碼是一樣的,兩個(gè)都是必須的,這樣的話經(jīng)過(guò)反復(fù)測(cè)試確實(shí)效果還是不錯(cuò)的,今天就說(shuō)到這里吧先,思路終于清晰了也。