iOS開發——iOS狀態列和導航欄的控制問題
導航欄控制
背景控制
在IOS7中使用barTintColor
來控制導航欄的背景色:
[[UINavigationBar appearance] setBarTintColor:[UIColor yellowColor]];
這個設定方法可以在AppDelegate
中設定,全域性可以生效。
如果希望使用圖片來作為導航的背景,那麼需要注意的是ios7中圖片的高度問題。上面提到過了,ios7導航欄的高度其實是算上狀態列的,即44+20=64個點的高度。可以通過setBackgroundImage
來設定:
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@ "nav_bg.png" ] forBarMetrics:UIBarMetricsDefault];
前景控制
前景控制分為標題控制和返回按鈕(等系統按鈕)的控制
標題需要通過setTitleTextAttributes
來設定,相對比較複雜一些,例如:
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8];
shadow.shadowOffset = CGSizeMake(0, 1 );
[[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
[UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:245.0/255.0 alpha:1.0], NSForegroundColorAttributeName,
shadow, NSShadowAttributeName,
[UIFont fontWithName:@ "HelveticaNeue-CondensedBlack" size:21.0], NSFontAttributeName, nil]];
設定返回按鈕(等系統按鈕)可以通過TintColor
,直接來設定顏色
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
顯示設定
有時我們希望導航欄不顯示,而有時又希望顯示,那麼最好通過每個個體的VC來控制,如果某個VC需要與其他VC有所區別,那麼最好是“負責到底”,即在進入VC時改變導航欄的顯示狀態,而退出時還原:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController.navigationBar setHidden:YES];
[self.rdv_tabBarController setTabBarHidden:YES animated:NO];
}
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController.navigationBar setHidden:NO];
[self.rdv_tabBarController setTabBarHidden:NO animated:NO];
}
如何在有導航欄的情況下定位控制元件的Y
可能初學ios的同學(尤其是通過手寫程式碼佈局的同學)都會有這麼個感受,為什麼我的控制元件有的時候明明定位在VC上,但會被導航欄遮住,那麼你可能會得出結論原點(0,0)是在螢幕的左上角被導航欄遮住的;而對於像UITableView
這樣的,設定了全屏鋪滿,怎麼就沒有被導航欄遮住呢?原點難道不在左上角?
筆者被這個問題困擾了很久,這裡談一下最近的一個理解。我們拿UITextView
來看
當我們把一個UITextView
放到一個沒有導航的VC中時:
UITextView *textView = [[UITextView alloc] init];
textView.frame = CGRectMake(10, 200, 300, 120);
textView.backgroundColor = [UIColor redColor];
textView.text = @"遊戲分兩種,一種是在生活中玩的,另一種是生活在其中的。這兩個世界相互矛盾,而兩位約翰就分別屬於這不同的世界。";
textView.font = [UIFont boldSystemFontOfSize:40];
textView.editable = NO;
[self.view addSubview:textView]
效果是這樣的,看起來並沒有什麼問題
然而如果我們把這個VC放到一個導航控制器中,同樣的程式碼卻是這樣結果
首先,看起來UITextView
距離裝置頂部的絕對距離似乎並沒有變化,但是請注意UITextView
的滾動條,滾動條竟然沒有頂部對齊,而且文字也向下移位了,看起來空出一大塊。仔細看空出的這段高度其實剛好是導航欄的高度64個點!!經過搜尋,我發現只要設定如下程式碼即可恢復這種異常的狀況:
self.automaticallyAdjustsScrollViewInsets = NO;
這下明白了,原來VC會對其內部的UIScrollView
的內容部分進行一個Inset
,這個Inset
在上半部分剛好就對應導航欄的高度,而UIScrollView
包括UITableView
和UITextView
等。到這裡,似乎有些問題明朗了:
-
VC中的view預設會對
UIScrollView
做一個適應導航欄的處理,由此推測,其實只要是VC中的控制元件,都是從裝置左上角的(0,0)開始算的,只是對於UIScrollView
,VC會自動調整一下內容的位置而已。 -
在有導航的情況下,可視範圍的Y座標就是從64開始的,除了
UIScrollView
的控制元件,定位的時候,都應當以(0,64)為原點;而UIScrollView
如果是全屏的,那麼無所謂,如果不是全屏的,請注意是否需要設定VC的automaticallyAdjustsScrollViewInsets
。