UINavigationBar 的某些事

NavigationBar 是我們常用的,昨天想到了一個 手機 QQ 空間狀態處對于 NavigationBar 處的處理,特此總結下這方面的。

UINavigationBar

在此,我們先了解下UINavigationController的層次圖,有助于我們更加的了解UINavigationBar

UINavigationController 層次

所以通俗地說就是,UINavigationController是個容器,里面可以裝很多UIViewController。裝這么多UIViewController讓用戶怎么控制它們呢,總得有個工具吧。這個工具就是UINavigationBar。一個容器就這么一個bar,相當于控制臺吧。但是,管理那么多UIViewController,控制臺上得按鈕啊、標題啊,都千篇一律是不是看起來太無聊了。為了解決這個問題,UINavigationController為每個UIViewController生成一個UINavigationBarItem,通過這個UINavigationBarItem可以改變控制臺“上面”得按鈕和標題。

簡單的說,UINavigationBar是UINavigationController的一個組成部分,就是上面的那個導航欄。UINavigationBar又有UINavigationItem組成。UINavigationItem則有title,按鈕,提示文本等組成,就是我們看到的title文字,右上角的按鈕。

  • NavigationItem在NavigationBar代表一個ViewController,具體一點兒來說就是每一個加到NavigationController的viewController都會有一個對應的NavigationItem.
  • 一個導航控制器控制多個視圖,NavigationBar上的leftItem,rightItem,title是由當前的視圖控制器控制的。
一、基本用法
一、基本用法
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 中設置有效,而且只有純代碼的時候才有效。storyboard 在根視圖中設置也是沒有效果的,以及其他的子視圖單獨設置都是沒有效果的哦。

[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[UINavigationBar appearance].titleTextAttributes =@{
                        NSForegroundColorAttributeName : [UIColor whiteColor]
                                                    };
[[UINavigationBar appearance] setBarTintColor:[UIColor blueColor]];

當然也可一直用用圖片改變的

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"nav"] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"nav"]  forBarMetrics:UIBarMetricsDefault];
三、隱藏導航欄
self.navigationController.navigationBar.hidden = YES;
狀態欄擋住了

但是注意有時狀態欄確是不會消失哦,解決這個問題則需要涉及到下面這個問題啦,提到edgesForExtendedLayout

self.edgesForExtendedLayout = UIRectEdgeNone;

edgesForExtendedLayout是一個類型為UIExtendedEdge的屬性,指定邊緣要延伸的方向。 因為iOS7鼓勵全屏布局,它的默認值很自然地是UIRectEdgeAll,四周邊緣均延伸,就是說,如果即使視圖中上有NavigationBar,下有tabBar,那么視圖仍會延伸覆蓋到四周的區域。

導航欄動態的消失

if (scrollView.contentOffset.y > 64) {
    
    [self.navigationController setNavigationBarHidden:YES animated:YES];
}
else
{
    [self.navigationController setNavigationBarHidden:NO animated:YES];
}

此處注意navigationBar.hidden與navigationBarHidden的區別

兩種方法都是可以隱藏導航欄的,隱藏之后依然可以使用push和pop方法。但是如果用navigationBar.hidden隱藏導航欄,我們可以繼續使用navigationBarHidden提供的滑動pop效果,如果用navigationBarHidden,這個操作將無效;但前者navigationBar.hidden沒有系統自動的動畫效果。

ps 對狀態欄處的處理:

此時注意 iOS 7 之后,我們改變狀態欄的情況對plist info 的View controller-based status bar appearance設置為YES,則狀態欄會根據各個UIViewController的配置改變,UIViewController中如果需要改變狀態欄則需要重載以下兩個方法:

//狀態欄是否隱藏
- (BOOL)prefersStatusBarHidden;
//狀態欄樣式
- (UIStatusBarStyle)preferredStatusBarStyle;

如果View controller-based status bar appearance為NO,則標示狀態欄不受UIViewController的單獨控制,那么這個時候狀態欄的控制還和iOS7以前的方式一樣,在需要修改的地方執行setStatusBarHidden。

 [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

這樣狀態欄就變成白色啦,但是 iOS 9之后 還是用前一種方法的,重寫一下下面這個方法的。

- (UIStatusBarStyle)preferredStatusBarStyle;

四、屏幕原點的改變

此處不對比了 iOS 7之前的,ios6, 確實是從status bar下面開始布局 (0,20),iOS 7之后都是從status bar 左上角(0,0)開始布局的,但是有時,我們也會遇到在 NavigationController 中是以(0,64)布局的,此處又是什么情況呢?先來看一下下面三個屬性:

  • extendedLayoutIncludesOpaqueBars
    默認值NO,這個屬性指定了當Bar使用了不透明圖片時,視圖是否延伸至Bar所在區域;因此,如果我們自定義了nav bar背景圖片,view會從導航欄下面開始布局。
  • edgesForExtendedLayout
    默認是UIRectEdgeAll,也就是全屏布局(iOS7中鼓勵這樣,這樣可以透過半透明的bar看到一些模模糊糊的內容),如果設置為UIExtendedEdgeNone,view就不會延伸到bar的后面了
  • automaticallyAdjustsScrollViewInsets
    默認值是YES,如果視圖里面存在唯一一個UIScrollView或其子類View,,那么它會自動設置相應的內邊距(如果有navbar的時候,這個內邊距是64,這樣scrollview可以占滿屏幕,內容在64像素以下,不會被遮到,滑動scrollview,可以透過半透明效果看到scrollview上面的內容)

所以說有時,我們發現原點位置變化了,就可以看看上述幾個屬性是否有設置改動的。經常我們用到 tableView 或 collectionView 的時候就需要設置 self.automaticallyAdjustsScrollViewInsets = NO, 不讓其自動調整。

備注

http://blog.csdn.net/mad1989/article/details/41516743
http://www.cnblogs.com/ygm900/p/3659619.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容