UINavigationController,UIViewController与UITabBarController的整合使用

576 阅读6分钟

文章来源:blog.csdn.net/rongxinhua/…

UINavigationController与UITabBarController是iOS开发中最常用的两种视图控制器,它们都属于UIViewController的子类,继承关系如下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. @interface UITabBarController : UIViewController <UITabBarDelegate, NSCoding>  
  2. @interface UINavigationController : UIViewController  

\

UINavigationController:同级页面之间的跳转,界面典型的特点就是页面上部有一UINavigationBar导航条,导航条可以设置标题、左上角的按钮(一般用于返回),右上角的按钮,也可以自定义这些元素。

UITabBarController:父子页面之间的嵌套关系,界面典型的特点是耍耍下部有一UITabBar选项组,通过点击Tab,可切换上面的视图的变换。\

UIViewController、UINavigationController、UITabBarController三者的整合使用,可以开发出大部分的App应用页面框架。

\

一、在我们项目AppDelegate中添加UIViewController

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. //把UIViewController添加的应用中:  
  2. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
  3. {  
  4.     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];  
  5.       
  6.     SplashViewController *splashViewController = [[SplashViewController alloc] initWithNibName:@"SplashViewController" bundle:nil];  
  7.     self.window.rootViewController = splashViewController;  
  8.       
  9.     self.window.backgroundColor = [UIColor whiteColor];  
  10.     [self.window makeKeyAndVisible];  
  11.     return YES;  
  12. }  


上面说过,UINavigationController与UITabBarController是UIViewController的子类,所以,也可以按这样的方式添加,主要看项目界面的需要。

\

二、UIViewController之间的跳转与传参

一般的应用程序都不会只有一个页面,而页面之间的跳转,可以这样调用:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. //从UIViewController跳转到另一个UIViewController  
  2. LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil];  
  3. [self presentViewController:loginViewController animated:true completion:^{}];  
  4. //从UIViewController返回上一个UIViewController  
  5. [self dismissViewControllerAnimated:true completion:^{}];  

很多从Android开发转过来的同事,都会问一个问题:两个页面之间怎么传递参数?

其实,Android通过Intent对象来跳转和传递参数,当前页面是拿不到下一个页面的实例;而在iOS中,我们是通过直接创建的方式创建下一个页面实例的,所以,你可以在下一个UIViewController实例中提供一个方法,供当前页面去给它设置参数就行。

在Android中,返回上一个页面,还是通过Intent来回传参数;而在iOS中,可通过设置代理的方式来传参。具体使用下面的例子中会看到。

\

三、由UIViewController跳转到UITabBarController

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. //从UIViewController跳转到UINavigationController  
  2. HomeViewController *homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];  
  3. UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:homeViewController];  
  4. [self presentViewController:navigationController animated:true completion:^{}];  

\

HomeViewController是一个UITabBarController子类,代码如下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. //HomeViewController是一个UITabBarController子类  
  2. @interface HomeViewController : UITabBarController<UITabBarControllerDelegate, HomeDelegate>  
  3. @end  

\

四、UITabBarController嵌套子页面

在本例中,这个UITabBarController还属于UINavigationController导航链中的一个环节,故可以调用导航控制器相应的方法。

UITabBarController本身可以嵌套多个子页面的,每个页面可以由一个UIViewController来提供。代码如下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  2. {  
  3.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  4.     if (self) {  
  5.         //设置导航标题  
  6.         self.title = @"Message";  
  7.         //设置导航左上角的按钮  
  8.         UIBarButtonItem *leftBtn = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(onLeftBtnClick:)];  
  9.         self.navigationItem.leftBarButtonItem = leftBtn;  
  10.         //设置导航右上角的按钮  
  11.         UIImage *img = [UIImage imageNamed:@"msgIcon"];  
  12.         UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc] initWithImage:img style:UIBarButtonItemStyleBordered target:self action:nil];  
  13.         self.navigationItem.rightBarButtonItem = rightBtn;  
  14.   
  15.         //新建Tab页面  
  16.         UserListViewController *userListViewController = [[UserListViewController alloc] initWithNibName:@"UserListViewController" bundle:nil];  
  17.         MessageListViewController *messageListViewController = [[MessageListViewController alloc] initWithNibName:@"MessageListViewController" bundle:nil];  
  18.         //添加Tab耍耍到Tab控制器  
  19.         self.viewControllers = @[messageListViewController, userListViewController];  
  20.         //设置UITabBarControllerDelegate代理  
  21.         self.delegate = self;  
  22.     }  
  23.     return self;  
  24. }  


五、UITabBarController子页面之间的切换\

HomeViewController实现了UITabBarControllerDelegate协议,可用于Tab切换时执行某此操作,如下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. //实现协议方法,用于切换Tab时,更改页面的标题  
  2. -(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {  
  3.     NSInteger index = tabBarController.selectedIndex;  
  4.     NSString *title;  
  5.     switch (index) {  
  6.         case 0:  
  7.             title = @"Message";  
  8.             break;  
  9.         case 1:  
  10.             title = @"User List";  
  11.             break;  
  12.     }  
  13.     self.title = title;  
  14. }  


在UITabBarController的子页面(为UIViewController实例)中,可以设置该子页面所对应的TabBar项的相关属性,如下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  2. {  
  3.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  4.     if (self) {  
  5.         // Custom initialization  
  6.         self.tabBarItem.title = @"User List";  
  7.         self.tabBarItem.image = [UIImage imageNamed:@"chatIcon01"];  
  8.     }  
  9.     return self;  
  10. }  


六、UITabBarController子页面跳转到UINavigationController的下一个页面

从UITabBarController子页面跳转到UINavigationController的下一个页面,注意:前提是UITabBarController是属于UINavigationController导航链中的一个节点。

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. //从UITabBarController的子页面跳转到UINavigationController的下一个页面:  
  2. ChatViewController *chatViewController = [[ChatViewController alloc] initWithNibName:@"ChatViewController" bundle:nil];  
  3. UITabBarController *homeController = self.tabBarController;  
  4. [chatViewController setHomeDelegate:homeController];  
  5. [self.tabBarController.navigationController pushViewController:chatViewController animated:true];  


这里说一下用代理来实现参数的回传,这个代理的宝义如下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. @protocol HomeDelegate <NSObject>  
  2. -(void) onComeback:(NSString*) message;  
  3. @end  


需要在下一个页面(例子中的ChatViewController)中,添加这个代理作为它的属性,如下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. @interface ChatViewController : UIViewController  
  2. @property (weak) id<HomeDelegate> homeDelegate;  
  3. @end  
  4.   
  5. @implementation ChatViewController  
  6. @synthesize homeDelegate;  
  7. @end  

\

七、返回上一个页面与参数回传

要从ChatViewController返回到上一个页面,可执行下面代码:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. [homeDelegate onComeback:@"Hello"];  
  2. [self.navigationController popViewControllerAnimated:true];  


这样,就可以实现了参数的回传。

\

UINavigationController的页面回退的两个常用方法:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片

  1. //返回导航的上一个页面  
  2. [self.navigationController popViewControllerAnimated:true];  
  3.   
  4. //返回导航的第一个页面  
  5. [self.navigationController popToRootViewControllerAnimated:true];  

---------------

典型的iPhone程序包含一个Window和几个UIViewController,每个UIViewController管理多个UIView(可能是UITableView、UIWebView, UIIMageView等)。这些UIView之间如何进行层次迭放,显示、隐藏、旋转、移动等都是由UIViewController、UITableViewController或UISplitController进行切换。

当你的程序具有层次化的工作流时,就比较适合使用UINavigationController来管理UIViewController,即用户可以从上一层界面进入下一层界面,在下一层界面处理完之后又可以简单地返回到上一层界面,UINavigationController使用堆栈的方式来管理UIViewController。

\

进入下一层界面的代码如下:

[self.navigationController pushViewController:nextController animated:YES];

\

返回上一层界面的代码如下:

[self.navigationController popViewControllerAnimated:YES];

\

当程序使用pushViewController()函数将ViewController增加到UINavigation Controller的时候, UINavigationController就会自动增加并显示一个(back)返回按钮,用户单击这个"back"按钮时就可以回到原先的界面。

UINavigationController的这种运行机制产生这样的效果,用户可以一层一层地进入更深的界面层次,然后又可以一层一层的按顺序返回,使用这样的方式来组织用户界面非常方便。

\