UINavigationController是iOS中常用的控制器,作用是用来管理多个视图控制器。主要管理有层级的控制器(也就是一层到下一层)。
UINavigationController内部管理视图控制器,主要是因为
UINavigationController里是栈结构,把视图控制器入栈和出栈的过程。也就是说,入栈,就是把视图控制器加到UINavigationController中,就可以控制视图在哪一个层次(页面)显示出来。简单来说,就是那么多个页面,你想让哪一个显示出来。
在UINavigationController中,至少有一个controller存在,这个视图就是根视图控制器(RootViewController)。
UINavigationController展示出来的视图,都是栈顶的controller的view。
导航控制器的 view 在 屏幕的上方,44像素高,与屏幕同宽。
navigationController
这是每一个导航控制器都有的属性,也就是说在UINavigationController中,加入多个视图控制器后,每一个视图控制器都可以通过self. navigationController来获取自己被哪个控制器所有
AppDelegate.m
#import "AppDelegate.h"
#import "RootViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
// 试图控制器
RootViewController *root = [[RootViewController alloc]init];
// 导航控制器
UINavigationController *rootNC = [[UINavigationController alloc]initWithRootViewController:root];
rootNC.navigationBar.barTintColor = [UIColor blackColor];
// 加图片或者加颜色的时候,(0,0)点就以导航左下角
// 没有加的话(0,0)点就是在屏幕的左上角
[rootNC.navigationBar setBackgroundImage:[UIImage imageNamed:@"2.png"] forBarMetrics:(UIBarMetricsDefault)];
self.window.rootViewController = rootNC;
[self.window makeKeyAndVisible];
[root release];
root = nil;
[rootNC release];
rootNC = nil;
return YES;
}
解释:
1、UINavigationController *rootNC = [[UINavigationController alloc]initWithRootViewController:root];
用根视图控制器来初始化导航控制器,将根视图控制器入栈。
2、rootNC.navigationBar.barTintColor设置导航控制器本身视图的颜色
3、[rootNC.navigationBar setBackgroundImage:[UIImage imageNamed:@"2.png"] forBarMetrics:(UIBarMetricsDefault)];设置导航控制器本身视图的背景图。
4、导航控制器,如果加上颜色或者图片,则(0,0)点就会在导航条左下角;如果本身没有加颜色或者图片,(0,0)点就是在屏幕的左上角。
5、self.window.rootViewController = rootNC;把导航控制器给window的根视图控制器。
RootViewController.m
#import "RootViewController.h"
#import "FirstViewController.h"
@interface RootViewController ()
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor yellowColor];
UIButton *btn = [UIButton buttonWithType:(UIButtonTypeSystem)];
btn.frame = CGRectMake(100, 64, 100, 100);
btn.backgroundColor = [UIColor blueColor];
[btn addTarget:self action:@selector(btnAction:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:btn];
//item
// title
// self.navigationItem.title = @"RootView";
UIView *v = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 44)];
v.backgroundColor = [UIColor redColor];
self.navigationItem.titleView = v;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"口可口可" style:UIBarButtonItemStylePlain target:self action:@selector(leftAction:)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"口合口合" style:UIBarButtonItemStylePlain target:self action:@selector(rightAction:)];
}
- (void)btnAction:(UIButton *)sender{
NSLog(@"点击了..");
FirstViewController *firstVC = [[FirstViewController alloc]init];
[self.navigationController pushViewController:firstVC animated:YES];
[firstVC release];
firstVC = nil;
}
解释:
1、在这个根视图控制器自己的view中,定义了一个Button,点击的时候,去加载一个视图FirstViewController,同时导航控制器把FirstViewController入栈。这样的效果,就是点击button的时候,打开一个view,这个view是FirstViewController的view。此时FirstViewController就是RootViewController的下一层。
2、self.navigationController,获取所在的导航控制器
3、pushViewController,把视图控制器入栈。(栈顶)
4、self.navigationItem.titleView,在导航控制器的view里添加一个view。
5、self.navigationItem.leftBarButtonItem,导航控制器的view的左边的一个按钮,可以返回上一级(或者返回你想去的控制器的view),当返回的时候,就会出栈,把自己和把下一级的所有控制器都销毁。
6、self.navigationItem.rightBarButtonItem,导航控制器view的右边的按钮,可以编辑当前页或者前进或者去到某个视图(依据addtarget的action里边怎么写)。
FirstViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
UIButton *btn = [UIButton buttonWithType:(UIButtonTypeSystem)];
btn.frame = CGRectMake(100, 100, 100, 100);
btn.backgroundColor = [UIColor blueColor];
[btn addTarget:self action:@selector(btnAction:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:btn];
// navigation中的controller
// NSLog(@"%@",self.navigationController.viewControllers);
// 隐藏自带的back
// 1、添加一个leftBar
// self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"口可口可" style:UIBarButtonItemStylePlain target:self action:@selector(leftAction:)];
// 2、直接隐藏
self.navigationItem.hidesBackButton = YES;
// NSLog(@"%@",self.navigationController);
NSLog(@"%@",self.navigationController.viewControllers);
}
- (void)btnAction:(UIButton *)sender{
NSLog(@"点击了..first");
// 出栈,出来的是最上面的ViewController
// 出栈的控制器会被销毁,数据就没了。
// [self.navigationController popViewControllerAnimated:YES];
// secondViewController
SecondViewController *secondVC = [[SecondViewController alloc]init];
[self.navigationController pushViewController:secondVC animated:YES];
[secondVC release];
secondVC = nil;
}
解释:
1、隐藏导航控制器view的back:
(1)我们自己添加一个leftBar
(2)直接隐藏self.navigationItem.hidesBackButton = YES;
2、[self.navigationController popViewControllerAnimated:YES];把自己从导航控制器的栈中出栈。若是不是栈顶的试图控制器出栈,则会把该视图控制器以上的所有视图控制器都出栈。所有出栈的控制器的数据全部销毁。
3、回到根视图控制器:[self.navigationController popToRootViewControllerAnimated:YES];就会把根视图控制器以上的试图控制器全部出栈,销毁。
4、去到指定视图控制器:
NSArray *temp = self.navigationController.viewControllers;
[self.navigationController popToViewController:temp[1] animated:YES];
先获取所在导航控制器里所有的试图控制器,然后去到指定试图控制器,把自己下一集的试图控制器,都出栈销毁。