UINavigationBar的常見用法總結(jié)

在項目中,我們經(jīng)常需要去定制導(dǎo)航欄及狀態(tài)欄的顯示樣式,或者顯示/隱藏。下面總結(jié)一下常見的用法。

設(shè)置導(dǎo)航欄的title

有兩種辦法:

  1. 通過navigationItem修改
    self.navigationItem.title = @"學(xué)習(xí)導(dǎo)航欄中";
  2. 通過ViewController修改
    self.title = @"學(xué)習(xí)導(dǎo)航欄中"

設(shè)置導(dǎo)航欄的背景顏色

self.navigationController.navigationBar.barTintColor = [UIColor greenColor];
效果:

bar_background_color.png

設(shè)置導(dǎo)航欄標(biāo)題的字體,顏色

NSDictionary *attributes = @{NSForegroundColorAttributeName : [UIColor cyanColor], NSFontAttributeName: [UIFont systemFontOfSize: 30]};
[self.navigationController.navigationBar setTitleTextAttributes: attributes];

效果:


title_font_and_color.png

設(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];
prompt.png

在設(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];
tintColor.png

隱藏導(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];
backbutton.png

這種方法的好處是,可以設(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的方案。


InfoPlist.png

在自己的視圖控制器類中,重寫兩個方法:

- (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é)束語

個人水平有限,如果文中有錯誤之處,歡迎指正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容