iOS中導(dǎo)航欄的基本使用匯總
一、設(shè)置導(dǎo)航欄樣式
設(shè)置導(dǎo)航欄的樣式可分為全局設(shè)置與局部設(shè)置;
1.全局設(shè)置
全局設(shè)置一般的都是在AppDelegate中設(shè)置,這樣整個(gè)app都會(huì)生效,相關(guān)的代碼與效果圖如下:
//1.設(shè)置導(dǎo)航欄背景顏色 [[UINavigationBar appearance] setBarTintColor:[UIColor orangeColor]]; //2.設(shè)置導(dǎo)航欄背景圖片 [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"navigationBarImg"] forBarMetrics:UIBarMetricsDefault]; //3.設(shè)置導(dǎo)航欄標(biāo)題樣式 [[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys: [UIColor purpleColor], NSForegroundColorAttributeName, [UIFont boldSystemFontOfSize:25], NSFontAttributeName, nil]]; //4.設(shè)置導(dǎo)航欄返回按鈕的顏色 [[UINavigationBar appearance] setTintColor:[UIColor greenColor]]; //5.設(shè)置導(dǎo)航欄隱藏 [[UINavigationBar appearance] setHidden:YES];
設(shè)置導(dǎo)航欄樣式效果圖
2.局部設(shè)置:
全局設(shè)置后,如果只有其中幾個(gè)頁(yè)面導(dǎo)航欄樣式不同,那么我們可以使用局部設(shè)置。
注意1:局部設(shè)置與全局設(shè)置方法相同,但調(diào)用方法的對(duì)象變成了"self.navigationController.navigationBar"
注意2:局部設(shè)置必須遵循一個(gè)原則:"進(jìn)入頁(yè)面時(shí)修改,離開(kāi)頁(yè)面時(shí)還原”。
比如我們進(jìn)入一個(gè)頁(yè)面,需要設(shè)置當(dāng)前導(dǎo)航欄的背景色為灰色,使用如下方法:
//進(jìn)入頁(yè)面時(shí)設(shè)置顏色:灰色 - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self.navigationController.navigationBar setBarTintColor:[UIColor grayColor]]; } //離開(kāi)頁(yè)面時(shí)還原為全局設(shè)置:橙色 - (void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [self.navigationController.navigationBar setBarTintColor:[UIColor orangeColor]]; }
二、解決自定義導(dǎo)航欄返回按鈕后側(cè)滑不可用問(wèn)題
iOS導(dǎo)航欄自帶的返回按鈕形式單一,所以大多情況下,我們都需要自定義導(dǎo)航欄返回按鈕。但是此時(shí)我們卻發(fā)現(xiàn)頁(yè)面的側(cè)滑返回功能不可用了。為了解決這個(gè)問(wèn)題,我們需要在App中使用我們自定義的導(dǎo)航控制控制器,示例代碼如下:
#import “BaseNavigationController.h" //第一步:設(shè)置自定義導(dǎo)航控制器使用UIGestureRecognizerDelegate @interface BaseNavigationController ()<UIGestureRecognizerDelegate> @end @implementation BaseNavigationController - (void)viewDidLoad { [super viewDidLoad]; //第二步:設(shè)置自定義導(dǎo)航控制器的側(cè)滑手勢(shì)的代理 self.interactivePopGestureRecognizer.delegate = self; } //第三步:實(shí)現(xiàn)代理方法 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ if (self.childViewControllers.count == 1) { // 表示用戶在根控制器界面,就不需要觸發(fā)滑動(dòng)手勢(shì), return NO; } return YES; } @end
三、隱藏導(dǎo)航欄底部的分割線
隱藏導(dǎo)航底部分割線也是我們偶爾會(huì)遇到的開(kāi)發(fā)需求,首先我們可以通過(guò)Xcode的Debug View Hierarchy功能查看導(dǎo)航欄的視圖結(jié)構(gòu),效果如下:
導(dǎo)航欄視圖層級(jí)圖
從圖中可以看出,導(dǎo)航欄的底部分割線是一個(gè)UIImageView對(duì)象,而且高度只有0.5,所以我們可以據(jù)此獲取到導(dǎo)航欄的底部分割線對(duì)象,在一個(gè)視圖控制器中實(shí)現(xiàn)此需求,代碼如下:
#import "TestViewController.h" @interface TestViewController () //第一步:設(shè)置一個(gè)屬性,存放導(dǎo)航欄底部分割線對(duì)象 @property (nonatomic, strong) UIImageView *navBarBottomImage; @end @implementation TestViewController - (void)viewDidLoad { [super viewDidLoad]; ////第三步:獲取導(dǎo)航欄底部分割線對(duì)象 UIImageView *navBarBottomImage = [self findNavBarBottomImage:self.navigationController.navigationBar]; self.navBarBottomImage = navBarBottomImage; } //第四步:設(shè)置分割線的顯示或隱藏 //進(jìn)入頁(yè)面隱藏分割線 - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; self.navBarBottomImage.hidden = YES; } //離開(kāi)頁(yè)面時(shí)顯示分割線 -(void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; self.navBarBottomImage.hidden = NO; } //第二步:添加用于獲取導(dǎo)航欄分割線的方法 //導(dǎo)航欄底部分割線是一個(gè)UIImageView,且高度不超過(guò)1.0個(gè)高度,可據(jù)此查找此對(duì)象 -(UIImageView *)findNavBarBottomImage:(UIView *)view { if ([view isKindOfClass:UIImageView.class] && view.bounds.size.height <= 1.0) { return (UIImageView *)view; } for (UIView *subview in view.subviews) { UIImageView *imageView = [self findNavBarBottomImage:subview]; if (imageView) { return imageView; } } return nil; }
四、導(dǎo)航欄引起的布局問(wèn)題
1.內(nèi)容偏移屬性:automaticallyAdjustsScrollViewInsets
automaticallyAdjustsScrollViewInsets是視圖控制器的一個(gè)屬性,默認(rèn)為YES,用于優(yōu)化滑動(dòng)類視圖(繼承于UIScrollView的視圖)在視圖控制里的顯示:
iOS系統(tǒng)的導(dǎo)航欄UINavigationBar與標(biāo)簽欄UITabBar默認(rèn)都是半透明模糊效果,在這種情況下系統(tǒng)會(huì)對(duì)視圖控制器的UI布局進(jìn)行優(yōu)化:視圖控制器里面第一個(gè)被添加進(jìn)去的視圖是滑動(dòng)類視圖,并且其Frame是整個(gè)屏幕大小時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)整其contenInset,以保證滑動(dòng)視圖里的內(nèi)容不被UINavigationBar與UITabBar遮擋。
但是對(duì)于普通的視圖,此時(shí)我們?nèi)匀恍枰⒁猓悍腔瑒?dòng)視圖的布局仍然要考慮導(dǎo)航欄和標(biāo)簽欄高度,注意不被遮擋,比如布局的時(shí)候加上導(dǎo)航欄高度,以免內(nèi)容被導(dǎo)航欄遮擋。
我們可以通過(guò)一段代碼來(lái)測(cè)試一下效果,在默認(rèn)導(dǎo)航欄(半透明)的視圖控制器里添加如下代碼:
//UITextView是滑動(dòng)視圖,內(nèi)容自動(dòng)向下偏移,不會(huì)被導(dǎo)航欄覆蓋 UITextView *leftTextView = [[UITextView alloc] init]; leftTextView.frame = CGRectMake(0, 0,100, kDeviceHeight); // leftTextView.backgroundColor = [UIColor lightGrayColor]; leftTextView.text = @"君不見(jiàn),黃河之水天上來(lái),奔流到海不復(fù)回。君不見(jiàn),高堂明鏡悲白發(fā),朝如青絲暮成雪。人生得意須盡歡,莫使金樽空對(duì)月。天生我材必有用,千金散盡還復(fù)來(lái)。"; leftTextView.font = [UIFont systemFontOfSize:18]; leftTextView.editable = NO; [self.view addSubview:leftTextView]; //UIView是非滑動(dòng)視圖,內(nèi)容被導(dǎo)航欄部分覆蓋 UIView *rightView= [[UIView alloc] initWithFrame:CGRectMake(150, 0, 100, 100)]; rightView.backgroundColor = [UIColor redColor]; [self.view addSubview:rightView];
導(dǎo)航欄透明情況下,滑動(dòng)視圖自動(dòng)偏移,普通視圖被遮擋
其實(shí),這種系統(tǒng)的優(yōu)化也是可以控制關(guān)閉的,關(guān)閉優(yōu)化之后,滑動(dòng)視圖就會(huì)和普通視圖一樣,如果還設(shè)置其布局的原點(diǎn)是(0,0),其內(nèi)容就會(huì)被導(dǎo)航欄所覆蓋,關(guān)鍵代碼如下:
//automaticallyAdjustsScrollViewInsets在11.0后失效,所以需要判斷 if (@available(iOS 11.0,*)) { scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; }else{ //automaticallyAdjustsScrollViewIn,關(guān)閉自動(dòng)偏移的系統(tǒng)優(yōu)化 self.automaticallyAdjustsScrollViewInsets = NO; }
2.邊緣延伸屬性:edgesForExtendedLayout
edgesForExtendedLayout也是視圖控制器的布局屬性,默認(rèn)值是UIRectEdgeAll,即:當(dāng)前視圖控制器里各種UI控件會(huì)忽略導(dǎo)航欄和標(biāo)簽的存在,布局時(shí)若設(shè)置其原點(diǎn)設(shè)置為(0,0),視圖會(huì)延伸顯示到導(dǎo)航欄的下面被覆蓋。
所以我們可以設(shè)置self.edgesForExtendedLayout=UIRectEdgeNone
,此時(shí)視圖控制器里內(nèi)容就會(huì)避開(kāi)導(dǎo)航欄和標(biāo)簽欄了,依然是上面的leftTextView和rightView,設(shè)置了UIRectEdgeNone之后的效果圖如下:
self.edgesForExtendedLayout=UIRectEdgeNone
3.導(dǎo)航欄透明屬性translucent
上述兩種屬性都是在解決導(dǎo)航欄半透明情況下的布局問(wèn)題,但是如果我們的需求就是導(dǎo)航欄不透明,那么視圖控制器里的控件就會(huì)默認(rèn)從(0,64)開(kāi)始布局了,設(shè)置導(dǎo)航欄不透明的方法如下:
self.navigationController.navigationBar.translucent= NO;
相關(guān)文章:
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- 關(guān)于iOS導(dǎo)航欄返回按鈕問(wèn)題的解決方法
- iOS實(shí)現(xiàn)頂部標(biāo)簽式導(dǎo)航欄及下拉分類菜單
- IOS仿今日頭條滑動(dòng)導(dǎo)航欄
- 詳解iOS11關(guān)于導(dǎo)航欄問(wèn)題
- iOS應(yīng)用開(kāi)發(fā)中導(dǎo)航欄按鈕UIBarButtonItem的添加教程
- iOS如何去掉導(dǎo)航欄(UINavigationBar)下方的橫線
- iOS App開(kāi)發(fā)中導(dǎo)航欄的創(chuàng)建及基本屬性設(shè)置教程
- 兩種iOS隱藏導(dǎo)航欄的正確方法
- iOS定制UISearchBar導(dǎo)航欄同步iOS11的方法
- iOS界面跳轉(zhuǎn)時(shí)導(dǎo)航欄和tabBar的隱藏與顯示功能
相關(guān)文章
IOS 靜態(tài)方法與動(dòng)態(tài)方法詳解
這篇文章主要介紹了IOS 靜態(tài)方法與動(dòng)態(tài)方法詳解的相關(guān)資料,需要的朋友可以參考下2017-02-02iOS實(shí)現(xiàn)獲取系統(tǒng)iTunes音樂(lè)的方法示例
這篇文章主要給大家介紹了關(guān)于iOS如何實(shí)現(xiàn)獲取系統(tǒng)iTunes音樂(lè)的相關(guān)資料,文中通過(guò)示例代碼給大家詳細(xì)介紹了實(shí)現(xiàn)的方法,并給大家介紹了MPMediaPickerController的相關(guān)知識(shí),對(duì)大家的學(xué)習(xí)或者工作具有一定的幫助,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11教你如何解決XCODE升級(jí)后插件不能用問(wèn)題
Xcode 每次更新有個(gè)很頭疼的問(wèn)題,就是插件都會(huì)失效,要重裝。 不得不說(shuō)好多插件還是非常方便能提高效率。那么如何來(lái)解決這個(gè)問(wèn)題呢,今天我們就來(lái)探討下。2015-11-11iOS上下文實(shí)現(xiàn)評(píng)價(jià)星星示例代碼
這篇文章主要介紹了iOS上下文實(shí)現(xiàn)評(píng)價(jià)星星的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03iOS動(dòng)畫(huà)案例(1) 類似于qq賬號(hào)信息里的一個(gè)動(dòng)畫(huà)效果
做一個(gè)類似于qq賬號(hào)信息里的一個(gè)動(dòng)畫(huà),感覺(jué)挺有意思,下面給大家分享iOS動(dòng)畫(huà)案例(1) 類似于qq賬號(hào)信息里的一個(gè)動(dòng)畫(huà)效果,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-01-01iOS開(kāi)發(fā)之通過(guò)銀行卡號(hào)獲取所屬銀行名稱
本文給大家分享一段代碼關(guān)于ios通過(guò)銀行卡號(hào)獲取所屬銀行名稱,代碼簡(jiǎn)單易懂,在項(xiàng)目開(kāi)發(fā)中經(jīng)常會(huì)遇到這樣的功能,需要的朋友一起學(xué)習(xí)吧2016-11-11KVO實(shí)現(xiàn)自定義文件復(fù)制進(jìn)度效果
這篇文章主要為大家詳細(xì)介紹了KVO實(shí)現(xiàn)自定義文件復(fù)制進(jìn)度效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08