在StoryBoard中添加NavigationController
在上網看到很多都是用xib添加,使用StoryBard的有兩種辦法,但我覺得下面用到那種方式比較好,直接在StoryBard中拖入一個NavigationController,在StoryBard中出現兩個視圖,一個是NavigationController,另一個是TableViewController。
TableViewController不是必要存在的,只是默認添加上去的,加入需要其他視圖,則可以把它刪除,重新拖入需要的視圖,在NavigationController中按Ctrl鍵拖到新的視圖中,這時彈出的Segue會比平常多了一項,它是屬于RelationShip Segue分組的root view controller。
使用該Segue后,會發現第二個視圖中出現了導航欄。把示意app啟動引導的那個箭頭拉到第一個視圖,也就是NavigationController前面,
啟動app會發現,app啟動并非引導到NavigationController,而是后來新加的那個視圖。在啟動后打開的那個頁面的導航欄中修改Title屬性為"首頁",那么往后我們也稱這個頁面為"首頁",再往StoryBoard上面拖一個新的視圖,在"首頁"中添加一個Button按鈕,給Button和新的頁面建立Segue,類型選擇為push,這個類型與往常用的Modal不一樣,使用后原本空白的頁面上多了導航欄和工具欄,然后在這個頁面的導航欄中修改Title屬性為"次頁",保存運行一下,當點擊Button跳轉到次頁的時候,發現導航欄多了一個后退的按鈕,按鈕上的文字也寫明是"首頁",故名思意就知道點擊該按鈕就能返回到"首頁"了
NavigationItem添加
上面提到的后退按鈕,其實是導航欄上面的一種導航欄元素,對于一個導航欄它會有LeftBarItem、RightBarItem、TitleView還有一個比較特殊的位于導航欄左邊的BackBarItem。經本人嘗試,如果一個導航欄上有BackBarItem和LeftBarItem,那么BackBarItem會被LeftBarItem覆蓋,但這個有可能是本人嘗試的范圍有點窄,涵蓋不了所有情況,按本人推斷有可能是最后一個加到導航欄的就顯示到導航欄上。那下面就演示一下單純在導航欄上添加NavagationItem。
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(selectLeftAction:)];self.navigationItem.leftBarButtonItem = leftButton; UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(selectRightAction:)];self.navigationItem.rightBarButtonItem = rightButton;
在上述代碼中添加了左部按鈕和右部按鈕,兩個按鈕都被綁定了點擊事件,調用不同的方法,如果點擊后無操作則傳入nil則可。效果如下
兩個按鈕的圖標有所差別,這個在初始化方法的第一個參數所控制,其他值和圖片分別如下表所示
加入TitleView的代碼如下所示
NSArray *array = [NSArray arrayWithObjects:@"元素1",@"元素2", nil];UISegmentedControl *segmentedController = [[UISegmentedControl alloc] initWithItems:array];segmentedController.segmentedControlStyle = UISegmentedControlSegmentCenter; [segmentedController addTarget:self action:@selector(segmentAction:) forControlEvents:UIControlEventValueChanged];self.navigationItem.titleView = segmentedController;
這樣程序運行起來就有一個分段控件在標題處
因為返回按鈕是選擇了push類型的Segue而自動生成的,而按鈕上的文字都是自動添加上去的,加入要給這個按鈕進行修改設置,單純構造一個UIBarButtonItem賦值到self.navigationItem.backBarButtonItem屬性上是不行的。因為這個self.navigationItem.backBarButtonItem并非本頁面的返回按鈕,實際是以本頁面為起始頁而導航到的下一頁的返回按鈕。引用一個網友的說法就是比如在AController跳轉到BController,在A設置了self.navigationItem.backBarButtonItem,這個backBarButtonItem為BController的self.navigationController.navigationBar.backItem.backBarButtonItem。那么在要設置這個返回按鈕則需要在HGNaviView1Controller中添加以下代碼
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"根視圖" style:UIBarButtonItemStyleDone target:self action:@selector(On_BackButton_Click)]; [self.navigationItem setBackBarButtonItem:backButton];
效果則如下圖
在NavicationController中有兩個屬性是設置Bar Visibility,一個是設置導航欄的可視性;另一個設置工具欄的可視性。
同樣也可以通過代碼設置
[self.navigationController setToolbarHidden:false animated:true];
通過上面兩種方式設置的結果都是全局的,凡是跟同一個NavigationController建立Segue的視圖都會受影響。往工具欄上面添加按鈕類似在導航欄上添加按鈕,都是使用UIBarButtonItem,但添加到工具欄時是通過一個數組,代碼如下所示
UIBarButtonItem *one = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];UIBarButtonItem *two = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:nil action:nil];UIBarButtonItem *three = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];UIBarButtonItem *four = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:nil action:nil];UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; [self setToolbarItems:[NSArray arrayWithObjects:flexItem, one, flexItem, two, flexItem, three, flexItem, four, flexItem, nil]];
當然ToolBar可以自行添加,但如果不把NavigationController統一建立的工具欄隱藏掉的話會導致視圖上會有兩個工具欄,假如只是個別頁面需要顯示工具欄的話個人還是覺得把NavigationController統一建立的工具欄隱藏,在需要的界面中自行添加工具欄
[self.navigationController setToolbarHidden:true animated:true];UIBarButtonItem *one = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];UIBarButtonItem *two = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:nil action:nil];UIBarButtonItem *three = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];UIBarButtonItem *four = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:nil action:nil];UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, self.view.frame.size.height - 44.0, self.view.frame.size.width, 44.0)];[toolBar setBarStyle:UIBarStyleDefault];toolBar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;[toolBar setItems:[NSArray arrayWithObjects: flexItem, one, flexItem, two, flexItem, three, flexItem, four, flexItem,nil]];[self.view addSubview:toolBar];
效果和上圖完全一樣
TabBarController使用
在使用過NavigationController之后使用TabBarController就容易上手了,在StoryBoard中拖入TabBarController,情況與NavigationController的類似,第一個頁面TabBarController并非會呈現到用戶界面中去,它只是起到一個管理各個子頁面的效果,每個選項卡的具體內容會在他們的視圖中編輯,這里默認會建立兩個Tab,
如果需要再多的Tab,就可以直接拖入對應的ViewController,在TabBarController頁面按Ctrl連接到新頁面建立Segue,這里的Segue類型又有不同,Relationship Segue分組中有一個view controllers,就選擇那個可以了,這樣在TabBarController中會多加了一個Tab。
Tab修改
每個Tab的圖標和文字都可以在相應的Tab視圖中修改,
圖標的尺寸是有限制的,在30*30,如果過大了就會有部分顯示不出來,而且就算是給的圖標是一個彩色的圖片,最終顯示在界面上的都只剩下一個輪廓,原圖與顯示在TabBar中的對比
在代碼中同樣可以用相應的屬性對Tab的標題和圖片進行設置
[self.tabBarItem setImage:[UIImage imageNamed:@"SunFlower.gif"]];[self.tabBarItem setTitle:@"第一選項卡"];
不過有另一個方法setFinishedSelectedImage:withFinishedUnselectedImage則可以把圖標完整顯示出來,如果圖標過大則會占用下面文字的空間,而且圖標會按原本的顏色顯示出來,圖標的顯示還會按照選項卡的選中狀態來決定
[self.tabBarItem setFinishedSelectedImage:[UIImage imageNamed:@"SunFlower.gif"] withFinishedUnselectedImage:[UIImage imageNamed:@"Ixia.gif"]];
選中時
未選中時
在每個TabBarItem中都有一個badgeValue屬性,用于設置Tab的小紅圈的值,他是NSString,所以可以給他賦的值就不局限在數字,還可是其他字符
self.tabBarItem.badgeValue=@"new";
Tab的數量可以無限地增加,但是在節目是最多可以顯示五個Tab標簽,如果Tab的數量多于5個的時候,原本第5個的Tab就會變成,并且點擊進去是一個帶TableView的導航頁,從第5個開始的Tab會在TableView中顯示,從TableView中導航到的Tab頁都會帶導航欄,以返回TabeView那一頁
導航欄上面還有編輯按鈕進入配置Tab的頁面
在這一頁中可以拖拽各個Tab標簽到底部的TabBar中以更改Tab在TabBar中的順序,而這里顯示的Tab是可以通過UITabBarController的customizableViewControllers屬性設定的,默認情況下它是和UITabBarController的viewController屬性(這個就是UITabBarController擁有Tab的集合)擁有相同的元素,但是也可以通過設置把第6個Tab從customizableViewControllers中去除
NSArray *viewControllers= self.tabBarController.viewControllers;NSMutableArray *newViewControllers=[NSMutableArray arrayWithCapacity:viewControllers.count-1];for (int i=0; i<[viewControllers count]-1; i++) { [newViewControllers addObject:[viewControllers objectAtIndex:i]];}self.tabBarController.customizableViewControllers=newViewControllers;
結果第6個Tab就不會出現在Configure頁面中了
而對于viewControllers有的Tab而customizableViewControllers沒有的Tab,則該部分Tab在編輯狀態下不會被移除出TabBar。
關于選中的Tab
通過selectedIndex和selectedViewController都可以獲取或設置被選中的Tab,對于設置selectedIndex和selectedViewController而言,僅僅能設置可以選中的Tab,并不能把頁面切換過去,而且對于More這個Tab來說還有點特別的情況
UITabBarController的tabBar屬性里面也可以通過selectedItem獲取選中的UITabBarItem,但是并不能給這個selectedItem賦值,這回引發異常。雖然UITabBar有一些方法是可以改變自身狀態,但不能給UITabBarController的tabBar修改自身狀態。
UITabBarController的事件
UITabBarController擁有一些事件,通過這些事件可以監測Tab發生變化,這需要給ViewController實現UITabBarControllerDelegate協議,然后設置tabBarController的delegate屬性
self.tabBarController.delegate=self;
事件歸為兩類,一類是單純tabBar上Tab的選中狀態發生變更前后出發的
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController -(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
先觸發前者再觸發后者,前者有一個布爾類型的返回值,如果返回的是False則會取消Tab的切換,但是通過代碼設置SelectedIndex除外。兩個參數tabBarController代表著起始的Tab,viewController代表著目標的Tab;
另一類是針對moreViewController的edit操作的
-(void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray *)viewControllers -(void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed -(void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed
WillBegin…是在進入Edit界面時觸發的,WillEnd…和didEnd….是在點擊了Done之后相繼觸發的。
新聞熱點
疑難解答