基本概念:導航視圖控制器(UINavigationController)是用於構建分層應用程序的主要工具,管理着多個內容視圖的換入和換出,並且自身提供了視圖切換的動畫效果(例如:相冊,QQ,微信等APP應用)。
它的父類是UIViewController,是所有視圖控制器的基類,導航控制器以棧的形式來實現,其本身也屬於視圖控制器。
下圖是UINavigationController的分層結構圖:
UINavigationController view層級
棧的基本概念與性質:
棧是一種數據結構,采用先進后出(后進先出)的原則。導航以棧的形式來管理視圖控制器,任何視圖控制器都可以放入棧中。
向棧里添加一個對象的操作稱為“入棧(push)”,即把對象推入到棧里;
第一個入棧的對象,通常被叫做“基棧”;最后一個入棧的對象,叫做“棧頂”;
在棧中刪除一個對象的操作叫做“出棧(pop)”;
當前顯示的視圖控制器,即為“棧頂”。選擇“返回”時,這個視圖控制器就“出棧”了。
導航控制器的基本樣式:
紅色部分為:導航控制器的導航欄(NavigationBar)一般來說主要負責視圖的彈出和控制主視圖;
黃色部分為:導航控制器顯示的主視圖區,主要顯示內容(用戶感興趣的區域);
藍色部分為:導航控制器的工具欄(UIToolBar),默認是隱藏的;
這些視圖共同構成了導航控制器。
下面用一個實例來簡單的介紹導航控制器(UINavigationController)的使用方法:
實現:1.在根視圖中間添加一個按鈕,名稱:“Push”。將標題設置為“RootVC”;
2.當單擊“Push”按鈕時,推送到下一個視圖控制器;
3.第二個視圖控制器標題“SecondVC”,在視圖中間初始化一個“isHidden”按鈕,將ToolBar顯示出來;
4.單擊按鈕時,隱藏導航欄和工具欄目;
實現代碼:
//1.先創建一個空白項目
//2.新建一個類:命名為“rootViewController”,繼承自“UIViewController”
//3.新建第二個類:命名為“SecondViewController”,繼承自“UIViewController”
Xcode5.1
//4.層級關系:AppDelegate.h -> rootViewController.h -> SecondViewController.h
//5.把rootViewController設為UINavigationController的“基棧”:
//在AppDelegate.m的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;方法里添加代碼:
rootViewController *rootVC = [[rootViewController alloc] init]; //簡單的初始化視圖控制器
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:rootVC]; //初始化並把rootVC定為導航控制器的“基棧”
self.window.rootViewController = navigation; //把navigation添加到根視圖控制器上
//6.設置rootViewController的屬性;
//在rootViewController.m里覆蓋方法同時添加按鈕事件:
-(void)loadView
{
//中間主要的顯示視圖:
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
seld.view =view;
view.backgroundColor = [UIColor yellowColor];
//標題:
self.title = @"rootVC";
//添加按鈕:
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(90,100,140,40);
[self.view addSubview:button];
[button setTitle:@"Push" forState:UIControlStateNormal];
[button addTarget:self action:@selector(PushVC) forControlEvents:UIControlEventTouchUpInside];
}
-(void)PushVC
{
SecondViewController *secondVC = [[SecondViewController alloc] init];
[self.navigationController pushViewController:secondVC animated:YES]; //此方法是導航控制器的推送方法,有1.回到“基棧”(popToRootViewController);2.去指定的視圖控制器(popToViewController);3.壓入一個視圖(pushViewController);4.返回上一個視圖(popViewControllerAnimated);
}
//7.設置SecondViewController的屬性及方法
//在SecondViewController.m里添加:
-(void)loadView
{
//主視圖顯示:
UIView *SecondVC = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] ];
[self.view addSubView:SecondVC];
SecondVC.backgroundColor = [UIColor darkGrayColor];
//標題:
self.title = @"SecondVC";
//isHidden按鈕:
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(90,100,140,40);
[button setTitle:@"isHidden" forState:UIControlStateNormal];
[button addTarget:self action:@selector(isHidden) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubView:button];
}
//isHidden事件方法,第一次出現時:Toolbar與NavigationBar同時顯示出來,當點擊按鈕后兩者隱藏,再次點擊后兩者顯現....
-(void)isHidden
{
if (self.navigationController.toolbarHidden) {
[self.navigationController setToolbarHidden:NO animated:YES]; //隱藏工具欄(下面)默認是YES(隱藏的)
[self.navigationController setNavigationBarHidden:NO animated:YES]; //隱藏導航欄(上面)默認是NO(不隱藏的)
}else{
[self.navigationController setToolbarHidden:YES animated:YES];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
//以上代碼完成實現目的
導航欄(UINavigationBar)的基本概念:
一個導航控制器包含有四個對象:UINavigationController;UINavigationBar;UIViewController;UINavigationItem;
其中NavigationItem存放在UINavigationBar上;
一個視圖控制器(UINavigationController)只有一個導航欄(UINavigationBar),卻包含若干個視圖控制器(UIViewController);
UINavigationItem放在UINavigationBar上,但是UINavigationItem不受UINavigationBar的控制,是由每一個視圖控制器(UIViewController)來控制它,且一個視圖控制器(UIViewController)控制一個UINavigationItem;
(細細體味一下以上概述,理清UINavigationController,UINavigationBar,UIViewController,UINavigationItem之間的關系!)
定制導航欄:
定制標題視圖:通過NavigationItem的titleView屬性,定制標題視圖。titleView屬性是一個視圖類,因此可以添加一個UIView的實例,也可以添加UIView子類,還可以在UIView的實例中添加子視圖。
// navigationItem.titleView常用屬性,添加一個視圖作標題
UIView *cVIew = [[UIView alloc] initWithFrame:CGRectMake(0,0,160,44);
cView.backgroundColor = [UIColor redColor];
self.navigationItem.titleView = cView; //self 指的是視圖控制器
[cView release];
//或者直接用文字標題:
self.title = @"cView"; //self 指UINavigationController
//系統給出了了幾種navigationBar樣式,但在IOS7系統上時,這幾種樣式就變成兩種了(這就是小編還有很多果粉不喜IOS7的緣由,系統強大了,但沒有了華麗感)
self.navigationController.navigationBar.barStyle = UIBarStyleDefault; //在IOS6中對應一個藍色漸變背景,IOS7中是個灰色背景
self.navigationController.navigationBar.barStyle = UIBaeStyleBlack; //在IOS6中對應一個不透明的黑色背景,IOS7中是黑色背景
self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque; //等於UIBaeStyleBlack樣式,但規定為棄用類型
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent; //同上面樣式一樣,也為棄用類型,但是透明
//這是自定義navigationBar背景的方法,使得navigationBar樣式不會太過單調
[navigationBar setBackgroundImage:[UIImage imageNamed:@"name.png"] forBarMetrics:UIBarMetricsDefault];
(setBackgroundImage方法的兩個參數,需要解釋一下:
UIBarMetricsDefault:用豎着(拿手機)時UINavigationBar的標准的尺寸來顯示UINavigationBar
UIBarMetricsLandscapePhone:用橫着時UINavigationBar的標准尺寸來顯示UINavigationBar
)
//下面是設置navigationBar背景顏色的方法,其中注意:在IOS6中,設置backgroundColor,是設置背景顏色;在IOS7上,是設置backButton的title字體顏色
self.navigationController.navigationBar.backgroundColor = [UIColor redColor];
//IOS7中設置navigationBar的背景顏色方法是:
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
// 修改導航控制器背景圖片的方式(IOS5以上)
[[UINavigationBar appearance] setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
注: 通過appearance可以設置全局的控件初始化外觀.不過在初始化成功以后,有單獨樣式需求亦可用同樣的方法修改.
UINavigationBar的標准高度是44,在iOS7之前可以通過44+X的方式實現背景+陰影的效果.從iOS7以后就不行了.
iOS7對UINavigationBar的標准進行重新的定義,其高度可以延伸到狀態欄.所以44+20的高度等於64.
而剛剛說的44+X方式不再適用於iOS7,iOS7的新規范是64+1.背景圖和陰影將單獨來設定,代碼如下:
//iOS7 新背景圖片設置方法 高度 必需是 64
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"name.png"] forBarPosition:UIBarPositionTopAttached barMetrics:UIBarMetricsDefaulr];
//iOS7 陰影需單獨設定 UIColor clearColor 是去掉字段 1像素陰影
[self.navigationController.navigationBar setShadowImage:[UIImage imageWithColor:[UIColor clearColor]]];
定制左右欄目:通過對導航欄的結構,我們了解到NavigationItem實例中有一個leftBarButtonItem(左)和rightBarButton(右),而這兩個屬性又是一個UIBarButtonItem的實例,因此,通過初始化UIBarButtonItem實例,設置導航欄的左,右欄目項。
例:左欄目:
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(leftButton:)]; //初始化一個Item
self.navigationItem.leftBarButtonItem = leftButton; //把名字叫“leftButton”的Item設為:leftBarButtonItem
backButtonItem.title = @"返回"; //默認情況下“backButton”的標題是前一個視圖控制器的title
-(void)leftButton:(id)sender
{
//action
}
右欄目:
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(selectRightAction:)];
self.navigationItem.rightBarButtonItem = rightButton; //self 指的是UINavigationController
-(void)rightButton:(id)sender
{
//action
}
(其中重點介紹下,系統帶了很多種UIBarButtonItem的風格,可以參照下圖(圖來自網絡):)
self.navigationController.navigationBar.wantsFullScreenLayout = YES; //viewController的一個屬性,這個屬性默認值是NO,如果設置為YES的話,如果statusbar,navigationbar, toolbar是半透明的話,viewController的view就會縮放延伸到它們下面,但注意一點兒tabBar不在范圍內,即無論該屬性是否為YES,view都不會覆蓋到tabbar的下方。
導航控制器中的工具欄:
在導航控制器中會有一個UIToolBar的實例,但默認是隱藏的,若需要顯示,需要通過以下方法將其打開:
[self.navigationController setToolbarHidden:NO animated:YES]; //顯示
導航控制器擁有只有一個UIToolBar實例,但UIToolBar所擁有的UIBarButtonItem實例是視圖控制器管理的。
例如:
[self setToolbarItems:itemsArray animated:YES]; //將UIBarButtonItem放入數組中,最后添加至UIToolBar中,self 指視圖控制器
[self.navigationController.toolbar setItems:itemsArray animated:YES]; //此代碼UIBarButtonItem不會出現在UIToolBar中,且toolbar是只讀屬性
自定義一個toolbar:
UIToolBar *toolbar = [[UIToolBar alloc] initWithFrame:CGRectMake(0,460-44*2,320,44)];
toolbar.barStyle = UIBarMetricsDefault; //系統風格跟navigationBar一樣
[self.view addSubView:toolbar]; //在“基棧”下添加
[toolbar release]; //釋放內存
//toolbar作為navigationController的工具欄,少不了的就是各種工具,在toolbar添加工具一般是定義一個數組,然后把數組添加到toolbar里面去
NSArray *array = @[addItem,titleItem,saveItem]; //"[]"里面的是UIBarButtonItem類的對象,不用“alloc”,默認是“autoRelease”的
[toolBar setItems:array animated:YES]; //把數組添加到toolbar里面,成為工具
//還有一種設置方法,不過系統默認導航視圖控制器的toolbar是隱藏的,使用要先設置顯示:
[self.navigationController setToolbarHidden:NO animated:YES];
[self setToolBarItems:array animated:YES]; //self 指的是視圖控制器,若使用這個方法就不需要自己初始化一個UIToolBar
//容易犯的錯誤寫法(需要知道的是:一個視圖控制器對應一個navigationBar和一個toolbar):
[self.navigationController.toolbar setItems:array animated:YES]; //這樣被會認為每個頁面上的toolbar都一樣
//添加進去的“工具”在顯示上的排列是順序排列,間隔是系統規定的,但相對與整個toolbar來說沒有相對於視圖的間隔,所以需要自己設置
UIBarButtonItem *jiange = [[UIBarButtonItem alloc] initWithBarButtonAystemItem:UIBarButtonSystemItemFexibleSpace target:self action:nil]; //此系統風格,作用:使兩個Item等分toolbar的視圖寬度
改正:NSArray *array = @[addItem,jiange,titleItem,jiange,saveItem];
[toolBar setItems:array animated:YES];
//自定義間隔,如上,只是風格方法不同
UIBarButtonItem *zdjiange = [[UIBarButtonItem alloc] initWithBarButtonAystemItem:UIBarButtonSystemItemFixedSpace target:self action:nil]; //自己常識一下其它的風格
zdjiange.with = 20;
(toolbar的使用基本上就是這些,其實跟navigationBar有點相似,只是間隔需要設置,可以多添加幾個Item,其它的屬性不用全部掌握,可以查API)
(可能學得比較淺,大家要是有補充可以留言,有問題的大家一起探討下,可以私下聯系:QQ790444804 微信:hgwchihuo
-------我是快樂的小尾巴`(*∩_∩*)′)