1、导航控制器的结构
如图,最上层的NavigationBar负责视图的弹出和控制主视图;中间的NavigationView用于显示主要内容;最下层的NavigationToolBar是工具栏,控制器默认它是隐藏的。
2、导航控制器的基本概念
一个导航控制器可以管理着多个视图控制,用栈的形式来管理。最开始显示的那个视图控制器最先入栈,当前显示的视图控制器即为栈顶,选择“返回”时,这个视图控制器就出栈了。UINavigationController的父类是UIViewController。
3、如何展现一个导航控制器
(1)首先创建一个空工程,这里不采用nib文件
(2)在AppDelegate.m中添加如下代码,这里我暂时把编译器自动生成的代码删掉了
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//创建一个视图控制器RootViewController
RootViewController *rootViewControl = [[RootViewController alloc]init];
//创建一个导航控制机器,将RootViewController作为导航控制器的根视图控制器
UINavigationController *navigationControl = [[UINavigationController alloc]initWithRootViewController:rootViewControl];
//将导航控制器付给窗体windows的根视图控制器
self.window.rootViewController = navigationControl;
}
(3)创建一个RootViewController类,继承自UIViewController,然后在-(void)loadView中添加如下代码
//如果ViewController的子类没有使用nib文件,那么就要重写该方法,才能创建它自己的特定的视图;如果没有重写该方法,默认空白的视图
- (void)loadView
{
/*******************为视图控制器创建一个视图*********************/
UIView *baseView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
baseView.backgroundColor = [UIColor orangeColor];
self.view = baseView;
/*******************为视图控制器创建一个视图*********************/
/***************通过HIDE按钮,隐藏导航栏和工具栏****************/
UIButton *hide = [UIButton buttonWithType:UIButtonTypeRoundedRect];
hide.frame = CGRectMake(160-50, 100, 100, 20);
[hide setTitle:@"HIDE" forState:UIControlStateNormal];
[hide addTarget:self action:@selector(HideClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:hide];
/***************通过HIDE按钮,隐藏导航栏和工具栏****************/
/***************通过PUSH按钮,显示一个新的视图****************/
UIButton *push = [UIButton buttonWithType:UIButtonTypeRoundedRect];
push.frame = CGRectMake(160-50, 160, 100, 20);
[push setTitle:@"PUSH" forState:UIControlStateNormal];
[push addTarget:self action:@selector(PushClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:push];
/**************通过PUSH按钮,显示一个新的视图****************/
/************使用UIBarButtonItem在导航栏上显示按钮***********/
UIBarButtonItem *rightitem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:self action:@selector(study)];
//错误写法
//self.navigationController.navigationItem.leftBarButtonItem = leftitem;
//原因分析:
/* 1.一个导航控制器里面有多个视图控制器,只有一个navigationBar和一个toolBar
* 2.navigationBar上的“按钮”是一个UINavigationItem(only one)
* 3.UINavigationItem不是由navigaBar控制,更不是由UINavigationController来控制
* 4.UINavigationItem是由当前视图控制器控制
*/
//正确写法
self.navigationItem.leftBarButtonItem = rightitem;//显示在左边
/************使用UIBarButtonItem在导航栏上显示按钮***********/
/****************将UIButton显示在导航栏上******************/
UIButton *item = [UIButton buttonWithType:UIButtonTypeRoundedRect];
item.frame = CGRectMake(90, 100, 140, 40);
[item setTitle:@"测试" forState:UIControlStateNormal];
[item addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithCustomView:item];
self.navigationItem.rightBarButtonItem = leftItem;//显示在右边
/****************将UIButton显示在导航栏上******************/
}
上面的代码实现了3个主要功能:A、隐藏导航栏和工具栏;B、压进了一个新的视图控制器;C、在导航栏上显示按钮;效果图如下:
这里给出实现A和B功能的两个方法:
#pragma mark - Target Action
-(void) HideClick
{
//显示工具栏和导航栏
if (self.navigationController.toolbarHidden) {
[self.navigationController setToolbarHidden:NO animated:YES];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}else{
//隐藏工具栏和导航栏
[self.navigationController setToolbarHidden:YES animated:YES];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
}
-(void)PushClick
{
//将第二个新的视图控制器入栈
SecondViewController *secondViewControl = [[SecondViewController alloc]init];
[self.navigationController pushViewController:secondViewControl animated:YES];//两个viewcontrol指向同一个navigationcontrol
}
(4)创建一个SecondViewController类,继承自UIViewController,然后仿照上面的代码在-(void)loadView添加四个按钮,效果图如下:
PUSH按钮实现的功能是压入一个新的视图控制器;
POP实现的功能是返回上一个视图控制器;
ROOT的功能是返回根视图控制器;
INDEX的功能是返回指定视图控制器;
这里给出四个按钮响应方法里面的内容:
#pragma mark - target action
-(void)pushClick
{
ThirdViewController *thirdViewControl = [[ThirdViewController alloc]init];
[self.navigationController pushViewController:thirdViewControl animated:NO];
}
-(void)popClick
{
[self.navigationController popViewControllerAnimated:YES];
}
-(void)rootClick
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
//返回指定位置的视图
-(void)indexClick
{
UIViewController *rootCV = [[self.navigationController viewControllers]objectAtIndex:0];//从0开始编号,返回导航控制器视图栈的数组
[self.navigationController popToViewController:rootCV animated:NO];//no标示没有切换的动画效果
}
4、小结
(1)一个UINavigationController对应一个NavigationBar的实例
(2)一个UINavigationController可以包含多个UIViewController
(3)每个UIViewController对应一个UINavigationItem实例
(4)一个UINavigaitonItem实例控制多个UIBarButtonItem(3个,左右中)
(5)一个UINavigationController对应一个UIToolBar的实例
(6)UIToolBar中的UIBarButtonItem也是由当前视图控制器管理,而不是由导航控制器管理