导航控制器UINavigationController是用来管理子控制器的切换的大管家
导航控制器是个管理型的控制器,他本身不显示视图内容,而是管理子控制器的视图显示
UINavigationController是UIViewController的子类
导航控制器的结构图:
【1】导航控制器的基本概念
导航控制器是对子视图控制器的管理-----栈结构的管理(先进后出,后进先出)
【2】导航控制器的基本用法
RootViewController
*rootVC = [[
RootViewController
alloc
]
init
];
// 创建一个导航控制器
//RootViewController: 让一个控制器作为导航控制器的根控制器
UINavigationController *nav = [[ UINavigationController alloc ] initWithRootViewController :rootVC];
// 创建一个导航控制器
//RootViewController: 让一个控制器作为导航控制器的根控制器
UINavigationController *nav = [[ UINavigationController alloc ] initWithRootViewController :rootVC];
NSLog(@"App:---%@", nav);
/*
// 原理
[nav.view addSubview:rootVC.view];
// 原理
[nav.view addSubview:rootVC.view];
*/
//
使用导航控制器作为
window
的根控制器
self.window.rootViewController = nav;
//
创建需要导航的二级界面控制器
SecondViewController
*secondVC = [[
SecondViewController
alloc
]
init
];
//push 到下一个控制器
//navigationController 是每一个视图控制器( UIViewController )都有的属性 , 如果说该控制器被放在某个导航控制器中管理,则能够直接拿到这个导航控制器,如果没有放到导航控制器中管理,则此属性对象为 nil
// NSLog(@"Root:----%@", self.navigationController);
//push 到下一个控制器
//navigationController 是每一个视图控制器( UIViewController )都有的属性 , 如果说该控制器被放在某个导航控制器中管理,则能够直接拿到这个导航控制器,如果没有放到导航控制器中管理,则此属性对象为 nil
// NSLog(@"Root:----%@", self.navigationController);
[self.navigationController pushViewController:secondVC animated:true];
Push pop root index:
if
(btn.
tag
==
1
) {
//PUSH
OtherViewController *otherVC = [[ OtherViewController alloc ] init ];
[ self . navigationController pushViewController :otherVC animated : true ];
} else if (btn. tag == 2 ) {
//POP
[ self . navigationController popViewControllerAnimated : true ];
} else if (btn. tag == 3 ) {
//ROOT // 回到根视图控制器
[ self . navigationController popToRootViewControllerAnimated : true ];
} else if (btn. tag == 4 ) {
//Index
UIAlertController *alertContrl = [ UIAlertController alertControllerWithTitle : @" 注意 " message : @" 请输入想跳转的第几个页面 " preferredStyle : UIAlertControllerStyleAlert ];
UIAlertAction *aciton = [ UIAlertAction actionWithTitle : @" 确定 " style : UIAlertActionStyleDefault handler :^( UIAlertAction *action) {
// 拿到 textField 当中的值
UITextField *txf = [[alertContrl textFields ] lastObject ];
NSInteger index = [txf. text integerValue ] ;
NSArray *viewcontrollers = self . navigationController . viewControllers ;
// 做安全处理
if (index < 0 || index >= viewcontrollers. count - 1 ) {
NSLog ( @" 输入违法 " );
return ;
}
UIViewController *vc = viewcontrollers[index];
[ self . navigationController popToViewController :vc animated : YES ];
}];
[alertContrl addTextFieldWithConfigurationHandler :^( UITextField *textField) {
textField. textAlignment = NSTextAlignmentCenter ;
textField. keyboardType = UIKeyboardTypeNumberPad ;
}];
[alertContrl addAction :aciton];
[ self presentViewController :alertContrl animated : YES completion : nil ];
}
//PUSH
OtherViewController *otherVC = [[ OtherViewController alloc ] init ];
[ self . navigationController pushViewController :otherVC animated : true ];
} else if (btn. tag == 2 ) {
//POP
[ self . navigationController popViewControllerAnimated : true ];
} else if (btn. tag == 3 ) {
//ROOT // 回到根视图控制器
[ self . navigationController popToRootViewControllerAnimated : true ];
} else if (btn. tag == 4 ) {
//Index
UIAlertController *alertContrl = [ UIAlertController alertControllerWithTitle : @" 注意 " message : @" 请输入想跳转的第几个页面 " preferredStyle : UIAlertControllerStyleAlert ];
UIAlertAction *aciton = [ UIAlertAction actionWithTitle : @" 确定 " style : UIAlertActionStyleDefault handler :^( UIAlertAction *action) {
// 拿到 textField 当中的值
UITextField *txf = [[alertContrl textFields ] lastObject ];
NSInteger index = [txf. text integerValue ] ;
NSArray *viewcontrollers = self . navigationController . viewControllers ;
// 做安全处理
if (index < 0 || index >= viewcontrollers. count - 1 ) {
NSLog ( @" 输入违法 " );
return ;
}
UIViewController *vc = viewcontrollers[index];
[ self . navigationController popToViewController :vc animated : YES ];
}];
[alertContrl addTextFieldWithConfigurationHandler :^( UITextField *textField) {
textField. textAlignment = NSTextAlignmentCenter ;
textField. keyboardType = UIKeyboardTypeNumberPad ;
}];
[alertContrl addAction :aciton];
[ self presentViewController :alertContrl animated : YES completion : nil ];
}
【3】
导航控制器的常用属性和方法
RootViewController.m文件:
self
.
view
.
backgroundColor
= [
UIColor
redColor
];
CGFloat screenWidth = [ UIScreen mainScreen ]. bounds . size . width ;
// CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
self . title = @"Root" ;
// 这种用法很少 , 一般直接设置 title
// self.navigationItem.title = @"Root";
// 设置导航栏的背景图片
UIImage
*img = [
UIImage
imageNamed
:
@"navbar_bg_normal.png"
];
//
修改图片的大小
UIGraphicsBeginImageContext ( CGSizeMake (screenWidth, 64 ));
[img drawInRect : CGRectMake ( 0 , 0 , screenWidth, 64 )];
img = UIGraphicsGetImageFromCurrentImageContext ();
UIGraphicsEndImageContext ();
// [self.navigationController.navigationBar setBackgroundImage:img forBarMetrics:UIBarMetricsDefault];
// 设置导航栏 title 的字体的颜色,大小
// self.navigationController.navigationBar.titleTextAttributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:20], NSForegroundColorAttributeName: [UIColor redColor]};
// 设置 titleView
UIButton *titileBtn = [ UIButton buttonWithType : UIButtonTypeCustom ];
[titileBtn setTitle : @"titleBtn" forState : UIControlStateNormal ];
[titileBtn addTarget : self action : @selector (titleBtnClick:) forControlEvents : UIControlEventTouchUpInside ];
titileBtn. backgroundColor = [ UIColor greenColor ];
titileBtn. frame = CGRectMake ( 0 , 0 , 100 , 40 );
UIGraphicsBeginImageContext ( CGSizeMake (screenWidth, 64 ));
[img drawInRect : CGRectMake ( 0 , 0 , screenWidth, 64 )];
img = UIGraphicsGetImageFromCurrentImageContext ();
UIGraphicsEndImageContext ();
// [self.navigationController.navigationBar setBackgroundImage:img forBarMetrics:UIBarMetricsDefault];
// 设置导航栏 title 的字体的颜色,大小
// self.navigationController.navigationBar.titleTextAttributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:20], NSForegroundColorAttributeName: [UIColor redColor]};
// 设置 titleView
UIButton *titileBtn = [ UIButton buttonWithType : UIButtonTypeCustom ];
[titileBtn setTitle : @"titleBtn" forState : UIControlStateNormal ];
[titileBtn addTarget : self action : @selector (titleBtnClick:) forControlEvents : UIControlEventTouchUpInside ];
titileBtn. backgroundColor = [ UIColor greenColor ];
titileBtn. frame = CGRectMake ( 0 , 0 , 100 , 40 );
self.navigationItem.titleView = titileBtn;
/*********
创建导航栏上左右两边的按钮
***********/
// 第一种方法
// 初始化一个 UIBarButtonItem 的实例,初始化一个系统的 Item
UIBarButtonItem *item1 = [[ UIBarButtonItem alloc ] initWithBarButtonSystemItem : UIBarButtonSystemItemBookmarks target : self action : @selector (item1Action:)];
// self.navigationItem.leftBarButtonItem = item1;
// 第二种方法
// 初始化一个带图片的 UIBarButtonItem 实例
UIBarButtonItem *item2 = [[ UIBarButtonItem alloc ] initWithImage :[ UIImage imageNamed : @"btn_search.png" ] style : UIBarButtonItemStyleDone target : self action : @selector (item2Action:)];
self . navigationItem . leftBarButtonItems = @[ item1, item2 ] ;
// 第三种方式
// 初始化一个只带标题的 UIBarButtonItem 实例
// UIBarButtonItem *item3 = [[UIBarButtonItem alloc] initWithTitle:@"hehe" style:UIBarButtonItemStyleDone target:self action:@selector(item3Action:)];
// self.navigationItem.leftBarButtonItem = item3;
// 第四种方法 ( 最常用的方法 )
// 通过自定义视图设置
UIButton *btn = [ UIButton buttonWithType : UIButtonTypeCustom ];
[btn setBackgroundImage :[ UIImage imageNamed : @"btn_search.png" ] forState : UIControlStateNormal ];
btn. frame = CGRectMake ( 0 , 0 , 33 , 32 );
UIBarButtonItem *item4 = [[ UIBarButtonItem alloc ] initWithCustomView :btn];
self . navigationItem . rightBarButtonItem = item4;
// 第一种方法
// 初始化一个 UIBarButtonItem 的实例,初始化一个系统的 Item
UIBarButtonItem *item1 = [[ UIBarButtonItem alloc ] initWithBarButtonSystemItem : UIBarButtonSystemItemBookmarks target : self action : @selector (item1Action:)];
// self.navigationItem.leftBarButtonItem = item1;
// 第二种方法
// 初始化一个带图片的 UIBarButtonItem 实例
UIBarButtonItem *item2 = [[ UIBarButtonItem alloc ] initWithImage :[ UIImage imageNamed : @"btn_search.png" ] style : UIBarButtonItemStyleDone target : self action : @selector (item2Action:)];
self . navigationItem . leftBarButtonItems = @[ item1, item2 ] ;
// 第三种方式
// 初始化一个只带标题的 UIBarButtonItem 实例
// UIBarButtonItem *item3 = [[UIBarButtonItem alloc] initWithTitle:@"hehe" style:UIBarButtonItemStyleDone target:self action:@selector(item3Action:)];
// self.navigationItem.leftBarButtonItem = item3;
// 第四种方法 ( 最常用的方法 )
// 通过自定义视图设置
UIButton *btn = [ UIButton buttonWithType : UIButtonTypeCustom ];
[btn setBackgroundImage :[ UIImage imageNamed : @"btn_search.png" ] forState : UIControlStateNormal ];
btn. frame = CGRectMake ( 0 , 0 , 33 , 32 );
UIBarButtonItem *item4 = [[ UIBarButtonItem alloc ] initWithCustomView :btn];
self . navigationItem . rightBarButtonItem = item4;
UIView
*view1 = [[
UIView
alloc
]
initWithFrame
:
CGRectMake
(
0
,
200
,
100
,
100
)];
view1. backgroundColor = [ UIColor blueColor ];
view1. backgroundColor = [ UIColor blueColor ];
[self.view addSubview:view1];
DetailViewController.m文件:
self
.
view
.
backgroundColor
= [
UIColor
cyanColor
];
self . title = @"Detail" ;
// 第四种方法 ( 最常用的方法 )
// 通过自定义视图设置
UIButton *btn = [ UIButton buttonWithType : UIButtonTypeCustom ];
[btn setBackgroundImage :[ UIImage imageNamed : @"btn_search.png" ] forState : UIControlStateNormal ];
btn. frame = CGRectMake ( 0 , 0 , 33 , 32 );
[btn addTarget : self action : @selector (btnClick:) forControlEvents : UIControlEventTouchUpInside ];
UIBarButtonItem *item4 = [[ UIBarButtonItem alloc ] initWithCustomView :btn];
// 一般在 iOS6 中我们经常这样自定义返回上一级的按钮
// 在 iOS7 以后,如果自定义返回上一级的按钮,则系统的抽屉式导航手势失效
self . navigationItem . leftBarButtonItem = item4;
// 设置导航栏的风格
self . navigationController . navigationBar . barStyle = UIBarStyleBlack ;
// 设置导航栏不透明
self . navigationController . navigationBar . translucent = false ;
// 设置导航栏颜色
self . navigationController . navigationBar . barTintColor = [ UIColor redColor ];
// 设置导航栏提示用户的内容 ( 用得比较少 )
self . title = @"Detail" ;
// 第四种方法 ( 最常用的方法 )
// 通过自定义视图设置
UIButton *btn = [ UIButton buttonWithType : UIButtonTypeCustom ];
[btn setBackgroundImage :[ UIImage imageNamed : @"btn_search.png" ] forState : UIControlStateNormal ];
btn. frame = CGRectMake ( 0 , 0 , 33 , 32 );
[btn addTarget : self action : @selector (btnClick:) forControlEvents : UIControlEventTouchUpInside ];
UIBarButtonItem *item4 = [[ UIBarButtonItem alloc ] initWithCustomView :btn];
// 一般在 iOS6 中我们经常这样自定义返回上一级的按钮
// 在 iOS7 以后,如果自定义返回上一级的按钮,则系统的抽屉式导航手势失效
self . navigationItem . leftBarButtonItem = item4;
// 设置导航栏的风格
self . navigationController . navigationBar . barStyle = UIBarStyleBlack ;
// 设置导航栏不透明
self . navigationController . navigationBar . translucent = false ;
// 设置导航栏颜色
self . navigationController . navigationBar . barTintColor = [ UIColor redColor ];
// 设置导航栏提示用户的内容 ( 用得比较少 )
self.navigationItem.prompt = @"hehehe";
//
弹出导航
[
self
.
navigationController
popViewControllerAnimated
:
true
];
【4】UINavigationBar的结构和基本用法