NavigationBar 是我們常用的乌妒,昨天想到了一個 手機 QQ 空間狀態(tài)處對于 NavigationBar 處的處理评凝,特此總結(jié)下這方面的追葡。
在此,我們先了解下UINavigationController
的層次圖肥哎,有助于我們更加的了解UINavigationBar
辽俗。
所以通俗地說就是,
UINavigationController
是個容器篡诽,里面可以裝很多UIViewController
崖飘。裝這么多UIViewController
讓用戶怎么控制它們呢,總得有個工具吧杈女。這個工具就是UINavigationBar
朱浴。一個容器就這么一個bar吊圾,相當(dāng)于控制臺吧。但是翰蠢,管理那么多UIViewController
项乒,控制臺上得按鈕啊、標(biāo)題啊梁沧,都千篇一律是不是看起來太無聊了檀何。為了解決這個問題,UINavigationController
為每個UIViewController
生成一個UINavigationBarItem
廷支,通過這個UINavigationBarItem
可以改變控制臺“上面”得按鈕和標(biāo)題频鉴。
簡單的說,UINavigationBar是UINavigationController的一個組成部分恋拍,就是上面的那個導(dǎo)航欄垛孔。UINavigationBar又有UINavigationItem組成。UINavigationItem則有title施敢,按鈕周荐,提示文本等組成,就是我們看到的title文字僵娃,右上角的按鈕概作。
- NavigationItem在NavigationBar代表一個ViewController,具體一點兒來說就是每一個加到NavigationController的viewController都會有一個對應(yīng)的NavigationItem.
- 一個導(dǎo)航控制器控制多個視圖默怨,NavigationBar上的leftItem,rightItem,title是由當(dāng)前的視圖控制器控制的仆嗦。
一、基本用法
self.title = @"TestTitle";// 與下面相同
//self.navigationItem.title = @"TestTitle";
// rightItem
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:@"Done"
style:UIBarButtonItemStyleDone
target:self
action:@selector(doneTestAction)];
// leftItem
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:@"Cancel"
style:UIBarButtonItemStylePlain
target:self
action:@selector(cancelTestAction)];
二、改變顏色
注意 title的顏色改變和 Item處的顏色方法是不同的
//改變顏色
self.navigationController.navigationBar.barTintColor = [UIColor blueColor];
//改變title顏色
self.navigationController.navigationBar.titleTextAttributes = @{
NSForegroundColorAttributeName : [UIColor redColor]
};
//改變 Item顏色
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
一般我們也常用下面這個方法改變垃僚,但是要注意我們一般只在AppDelegate中有效,或者是 UINavagaitonController中的 RootController 中設(shè)置有效规辱,而且只有純代碼的時候才有效谆棺。storyboard 在根視圖中設(shè)置也是沒有效果的,以及其他的子視圖單獨設(shè)置都是沒有效果的哦罕袋。
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[UINavigationBar appearance].titleTextAttributes =@{
NSForegroundColorAttributeName : [UIColor whiteColor]
};
[[UINavigationBar appearance] setBarTintColor:[UIColor blueColor]];
當(dāng)然也可一直用用圖片改變的
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"nav"] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"nav"] forBarMetrics:UIBarMetricsDefault];
三改淑、隱藏導(dǎo)航欄
self.navigationController.navigationBar.hidden = YES;
但是注意有時狀態(tài)欄確是不會消失哦,解決這個問題則需要涉及到下面這個問題啦浴讯,提到edgesForExtendedLayout
self.edgesForExtendedLayout = UIRectEdgeNone;
edgesForExtendedLayout
是一個類型為UIExtendedEdge的屬性朵夏,指定邊緣要延伸的方向。 因為iOS7鼓勵全屏布局榆纽,它的默認值很自然地是UIRectEdgeAll仰猖,四周邊緣均延伸捏肢,就是說,如果即使視圖中上有NavigationBar饥侵,下有tabBar鸵赫,那么視圖仍會延伸覆蓋到四周的區(qū)域。
導(dǎo)航欄動態(tài)的消失
if (scrollView.contentOffset.y > 64) {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
else
{
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
此處注意navigationBar.hidden與navigationBarHidden的區(qū)別:
兩種方法都是可以隱藏導(dǎo)航欄的躏升,隱藏之后依然可以使用push和pop方法辩棒。但是如果用navigationBar.hidden隱藏導(dǎo)航欄鬼吵,我們可以繼續(xù)使用navigationBarHidden提供的滑動pop效果嚎莉,如果用navigationBarHidden奏夫,這個操作將無效序目;但前者navigationBar.hidden沒有系統(tǒng)自動的動畫效果今布。
ps 對狀態(tài)欄處的處理:
此時注意 iOS 7 之后帘靡,我們改變狀態(tài)欄的情況對plist info 的View controller-based status bar appearance
設(shè)置為YES拒秘,則狀態(tài)欄會根據(jù)各個UIViewController的配置改變渺杉,UIViewController中如果需要改變狀態(tài)欄則需要重載以下兩個方法:
//狀態(tài)欄是否隱藏
- (BOOL)prefersStatusBarHidden;
//狀態(tài)欄樣式
- (UIStatusBarStyle)preferredStatusBarStyle;
如果View controller-based status bar appearance為NO双霍,則標(biāo)示狀態(tài)欄不受UIViewController的單獨控制砚偶,那么這個時候狀態(tài)欄的控制還和iOS7以前的方式一樣,在需要修改的地方執(zhí)行setStatusBarHidden洒闸。
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
這樣狀態(tài)欄就變成白色啦染坯,但是 iOS 9之后 還是用前一種方法的,重寫一下下面這個方法的丘逸。
- (UIStatusBarStyle)preferredStatusBarStyle;
四单鹿、屏幕原點的改變
此處不對比了 iOS 7之前的,ios6, 確實是從status bar下面開始布局 (0,20)深纲,iOS 7之后都是從status bar 左上角(0仲锄,0)開始布局的,但是有時湃鹊,我們也會遇到在 NavigationController 中是以(0儒喊,64)布局的,此處又是什么情況呢币呵?先來看一下下面三個屬性:
-
extendedLayoutIncludesOpaqueBars
默認值NO怀愧,這個屬性指定了當(dāng)Bar使用了不透明圖片時,視圖是否延伸至Bar所在區(qū)域余赢;因此芯义,如果我們自定義了nav bar背景圖片,view會從導(dǎo)航欄下面開始布局妻柒。 -
edgesForExtendedLayout
默認是UIRectEdgeAll扛拨,也就是全屏布局(iOS7中鼓勵這樣,這樣可以透過半透明的bar看到一些模模糊糊的內(nèi)容)蛤奢,如果設(shè)置為UIExtendedEdgeNone鬼癣,view就不會延伸到bar的后面了 -
automaticallyAdjustsScrollViewInsets
默認值是YES陶贼,如果視圖里面存在唯一一個UIScrollView或其子類View,待秃,那么它會自動設(shè)置相應(yīng)的內(nèi)邊距(如果有navbar的時候拜秧,這個內(nèi)邊距是64,這樣scrollview可以占滿屏幕章郁,內(nèi)容在64像素以下枉氮,不會被遮到,滑動scrollview暖庄,可以透過半透明效果看到scrollview上面的內(nèi)容)
所以說有時聊替,我們發(fā)現(xiàn)原點位置變化了,就可以看看上述幾個屬性是否有設(shè)置改動的培廓。經(jīng)常我們用到 tableView 或 collectionView 的時候就需要設(shè)置 self.automaticallyAdjustsScrollViewInsets = NO, 不讓其自動調(diào)整惹悄。
備注
http://blog.csdn.net/mad1989/article/details/41516743
http://www.cnblogs.com/ygm900/p/3659619.html