在項目中,我們經(jīng)常需要去定制導(dǎo)航欄及狀態(tài)欄的顯示樣式,或者顯示/隱藏。下面總結(jié)一下常見的用法。
設(shè)置導(dǎo)航欄的title
有兩種辦法:
- 通過navigationItem修改
self.navigationItem.title = @"學(xué)習(xí)導(dǎo)航欄中"; - 通過ViewController修改
self.title = @"學(xué)習(xí)導(dǎo)航欄中"
設(shè)置導(dǎo)航欄的背景顏色
self.navigationController.navigationBar.barTintColor = [UIColor greenColor];
效果:

設(shè)置導(dǎo)航欄標(biāo)題的字體,顏色
NSDictionary *attributes = @{NSForegroundColorAttributeName : [UIColor cyanColor], NSFontAttributeName: [UIFont systemFontOfSize: 30]};
[self.navigationController.navigationBar setTitleTextAttributes: attributes];
效果:

設(shè)置導(dǎo)航欄背景圖片
這里為了簡單起見,用顏色繪制出圖片。
UIImage *image1 = [UIImage imageWithColor: [UIColor redColor]];
UIImage *image2 = [UIImage imageWithColor: [UIColor blueColor]];
UINavigationBar *navBar = self.navigationController.navigationBar;
[navBar setBackgroundImage: image1 forBarMetrics: UIBarMetricsDefault];
[navBar setBackgroundImage: image2 forBarMetrics: UIBarMetricsCompact];
設(shè)定背景圖片時,要指定圖片適用的場合。UIBarMetricsDefault用于豎屏?xí)r,UIBarMetricsCompact用于橫屏?xí)r。
設(shè)置導(dǎo)航欄為透明效果
導(dǎo)航欄默認就是半透的效果,但如果想實現(xiàn)alpha值從0到1的任意透明度,可用下面的代碼。
CGFloat alphaValue = 0.2; //可設(shè)為0到1之間的任意值
UINavigationBar *navBar = self.navigationController.navigationBar;
[navBar setBackgroundImage: [UIImage imageWithColor: [UIColor colorWithRed: 0 green: 0 blue: 1 alpha: alphaValue]] forBarMetrics: UIBarMetricsDefault];
如果需要在拖動ScrollView的過程中,修改導(dǎo)航欄的透明度,就要用到上面的代碼。
隱藏導(dǎo)航欄下方的分隔線
導(dǎo)航欄下方,默認帶有一條灰色的分隔線。如果想要隱藏,需要同時設(shè)置和backgroundImage和shadowImage兩個屬性。如果不設(shè)置backgroundImage,那么即使設(shè)了shadowImage,也不會生效。
[self.navigationController.navigationBar setBackgroundImage: [UIImage new] forBarMetrics: UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage new];
修改導(dǎo)航欄下方的分隔線顏色
既然為shadowImage賦值為[UIImage New]時,可以隱藏分隔線,那么我們也可以根據(jù)此原理,來修改分隔線的顏色。
[self.navigationController.navigationBar setBackgroundImage: [UIImage new] forBarMetrics: UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage imageWithColor: [UIColor redColor]];
在導(dǎo)航欄的標(biāo)題上方增加一個提示文字
self.navigationItem.prompt = @"Navigation prompts appear at the top.";
UIImage *image1 = [UIImage imageWithColor: [UIColor yellowColor]];
UIImage *image2 = [UIImage imageWithColor: [UIColor purpleColor]];
UINavigationBar *navBar = self.navigationController.navigationBar;
[navBar setBackgroundImage: image1 forBarMetrics: UIBarMetricsDefaultPrompt];
[navBar setBackgroundImage: image2 forBarMetrics: UIBarMetricsCompactPrompt];

在設(shè)置了prompt的情況下,導(dǎo)航欄的高度會變大。相對應(yīng)的,新增了兩種BarMetrics:UIBarMetricsDefaultPrompt和UIBarMetricsCompactPrompt,分別對應(yīng)于豎屏和橫屏。
設(shè)置導(dǎo)航欄左右兩側(cè)的按鈕
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle: @"返回" style: UIBarButtonItemStylePlain target: self action: @selector(onBack)];
UIBarButtonItem *closeItem = [[UIBarButtonItem alloc] initWithTitle: @"關(guān)閉" style: UIBarButtonItemStylePlain target: self action: @selector(onClose)];
self.navigationItem.leftBarButtonItems = @[backItem, closeItem];
UIBarButtonItem *right1 = [[UIBarButtonItem alloc] initWithTitle: @"右1" style: UIBarButtonItemStylePlain target: nil action: nil];
UIBarButtonItem *right2 = [[UIBarButtonItem alloc] initWithTitle: @"右2" style: UIBarButtonItemStylePlain target: nil action: nil];
self.navigationItem.rightBarButtonItems = @[right1, right2];
設(shè)置導(dǎo)航欄的標(biāo)題為視圖
UISegmentedControl *segControl = [[UISegmentedControl alloc] initWithItems:@[@"男生",@"女生", @"全部"]];
[segControl setSelectedSegmentIndex:0];
self.navigationItem.titleView = segControl;

設(shè)置導(dǎo)航欄的渲染顏色
UINavigationBar的tintColor屬性,可以用來修改返回按鈕,以及左右兩側(cè)的按鈕的文字的顏色。
self.title = NSStringFromClass([self class]);
self.navigationController.navigationBar.tintColor = [UIColor yellowColor];
UIBarButtonItem *right1 = [[UIBarButtonItem alloc] initWithTitle: @"右1" style: UIBarButtonItemStylePlain target: nil action: nil];
UIBarButtonItem *right2 = [[UIBarButtonItem alloc] initWithTitle: @"右2" style: UIBarButtonItemStylePlain target: nil action: nil];
self.navigationItem.rightBarButtonItems = @[right1, right2];

隱藏導(dǎo)航欄
self.navigationController.navigationBarHidden = YES;
修改返回按鈕
方法1:修改UINavigationItem的leftBarButtonItem(s)
UIImage *leftButtonIcon = [[UIImage imageNamed:@"titlebar_back_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithImage:leftButtonIcon
style:UIBarButtonItemStylePlain
target:self
action:@selector(goToBack)];
UIBarButtonItem *negaSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negaSpacer.width = -20.f;
self.navigationItem.leftBarButtonItems = @[negaSpacer, leftButton];

這種方法的好處是,可以設(shè)定返回按鈕的響應(yīng)函數(shù);但是也會帶來一個問題,就是從左邊屏幕的邊緣,向右滑動時,不能返回上級界面了,也就是右滑手勢失效了。解決辦法是,在push一個ViewController之后,將self.navigationController.interactivePopGestureRecognizer.delegate 設(shè)為nil.
TestBackButton *vc = [TestBackButton new];
[self.navigationController pushViewController: vc animated: YES];
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
方法2:設(shè)置返回按鈕的圖片,將標(biāo)題置為空字符串
UIImage *backButtonBackgroundImage = [UIImage imageNamed:@"Menu"];
id appearance = [UIBarButtonItem appearanceWhenContainedIn:[CustomBackButtonNavController class], nil];
[appearance setBackButtonBackgroundImage:backButtonBackgroundImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
// Provide an empty backBarButton to hide the 'Back' text present by
// default in the back button.
//
// NOTE: You do not need to provide a target or action. These are set
// by the navigation bar.
// NOTE: Setting the title of this bar button item to ' ' (space) works
// around a bug in iOS 7.0.x where the background image would be
// horizontally compressed if the back button title is empty.
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithTitle:@" " style:UIBarButtonItemStylePlain target:nil action:NULL];
self.navigationItem.backBarButtonItem = backBarButton;
這種方法不會影響右滑手勢,但是返回按鈕的響應(yīng)函數(shù)是系統(tǒng)內(nèi)置的,無法修改,即使你指定了target和action,也不會被調(diào)用。
另外需要注意的是,假設(shè)視圖控制器A設(shè)置了backBarButtonItem,那么只有當(dāng)從A跳轉(zhuǎn)到B時,才會用到這些設(shè)置。這和leftBarButtonItem(s)和rightBarButtonItem(s)是不同的。
設(shè)置狀態(tài)欄樣式及是否隱藏
在iOS7及以后的版本中,蘋果推薦使用基于ViewController的方案,UIApplication類中的setStatusBarStyle, setStatusBarHidden等方法將被廢棄。通過在Info.plist中添加UIViewControllerBasedStatusBarAppearance,并將其置設(shè)為YES,APP就聲明自己使用基于ViewController的方案。

在自己的視圖控制器類中,重寫兩個方法:
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
但是要注意的是,如果視圖是嵌入在容器類的視圖控制器內(nèi),如UINavigationController,那么框架會去調(diào)用容器視圖控制器的上述兩個方法。所以需要自定義一個UINavigationController的子類,重寫上述的兩個方法。
- (UIStatusBarStyle)preferredStatusBarStyle {
return self.topViewController.preferredStatusBarStyle;
}
- (BOOL)prefersStatusBarHidden {
return self.topViewController.prefersStatusBarHidden;
}
結(jié)束語
個人水平有限,如果文中有錯誤之處,歡迎指正。