导航视图控制器
一 导航视图控制器 ----以栈的形式管理,先进后出原则
//导航视图控制器 控制视图控制器的控制器
//导航控制器 至少要控制一个视图控制器 而被控制的控制器 称之为导航控制的根视图控制器
//导航控制器 最大的作用 是控制视图控制器之间的跳转 以及返回的层级关系
RootViewController *rootViewVc = [[RootViewController alloc]init];
UINavigationController *rootNav = [[UINavigationController alloc]initWithRootViewController:rootViewVc];
self.window.rootViewController = rootNav;
//设置导航栏标题
self.navigationItem.title = @“”;
//设置导航栏背景颜色
self.navigationController.navigationBar.barTintColor = [];
//给导航栏添加背景图片
//给导航栏设置图片 要给合适的图片
//如果图片太小 会铺满整个导航栏
//如果图片太大 会显示不完整
[self.navigationController.navigationBar setBackGroundImage:[UIImage imageNamed:@“”]forBarMetrics:UIBarMetricsDefault];
//系统图片样式的barButton
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:self action:@selector(leftButtonAction:)];
self.navigationItem.leftBarButtonItem = leftButton;
//自定义文字样式的barButton
UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc]initWithTitle:@"你猜" style:UIBarButtonItemStylePlain target:self action:@selector(leftButtonAction:)];
self.navigationItem.leftBarButtonItem = leftBarButton;
//自己设置图片barButton
UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"x.jpg"] style:UIBarButtonItemStylePlain target:self action:@selector(leftBarButtonAction:)];
self.navigationItem.leftBarButtonItem = leftBarButton;
//自定义barButton 自己用图片添加button,自定义的view作为导航条的子视图
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(0, 0, 30, 30);
[button setBackgroundImage:[UIImage imageNamed:@"x.jpg"] forState:UIControlStateNormal];
UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc]initWithCustomView:button];
self.navigationItem.leftBarButtonItem = leftBarButton;
//多个button自定义 把多个button添加到view上
UIView *myView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 90, 30)];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
button1.frame = CGRectMake(0, 0, 30, 30);
[button1 setBackgroundImage:[UIImage imageNamed:@"x.jpg"] forState:UIControlStateNormal];
[myView addSubview:button1];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
button2.frame = CGRectMake(30, 0, 30, 30);
[button2 setBackgroundImage:[UIImage imageNamed:@"x.jpg"] forState:UIControlStateNormal];
[myView addSubview:button2];
UIButton *button3 = [UIButton buttonWithType:UIButtonTypeSystem];
button3.frame = CGRectMake(60, 0, 30, 30);
[button3 setBackgroundImage:[UIImage imageNamed:@"x.jpg"] forState:UIControlStateNormal];
[myView addSubview:button3];
UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc]initWithCustomView:myView];
self.navigationItem.leftBarButtonItem = leftBarButton;
//导航栏是由navigationBar 和contentView 组成的高度是44,上边的状态栏高度是20,所以两个部分加起来高度是64,
//导航栏默认是透明的 透明的情况下0 0 点是从设备的最左上角开始的
//如果设置成不透明的0 0 点 是从导航栏下方的左上角开始的
self.navigationController.navigationBar.translucent = NO;//关闭半透明状态
//导航控制器控制的所有所有视图控制器 都是存在一个数组当中的界面生成之后 才会存在 界面返回则会消失
/*
UIViewController *vc = self.navigationController.viewControllers[0];
vc.view.backgroundColor = [UIColor redColor];
*/
for (UIViewController *vc in self.navigationController.viewControllers)
{
NSLog(@"第一个界面:%@",[vc class]);
}
// 取出栈顶的控制器
UIViewController *topVc = self.navigationController.topViewController;
NSLog(@"栈顶:%@",[topVc class]);
// 当前所在的控制器
UIViewController *visibleVc = self.navigationController.visibleViewController;
NSLog(@"当前显示:%@", [visibleVc class]);
}
#pragma mark --- barButton触发方法 Left --- push推出下一个界面
- (void)leftBarButtonAction:(UIBarButtonItem *)barButton
{
NSLog(@"leftButtonAction");
SecondViewController *secondViewVc = [[SecondViewController alloc]init];
[self.navigationController pushViewController:secondViewVc animated:YES];
[secondViewVc release];
}
#pragma mark --- leftBarButtonAction —返回到上一界面
- (void)leftBarButtonAction:(UIBarButtonItem *)barButton
{
NSLog(@"返回");
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark --- rightBarButtonAction —返回到指定的导航视图控制器
- (void)rightBarButtonAction:(UIBarButtonItem *)barButton
{
// 返回到指定的试图控制器
// 前提条件:这个控制器之前必须生成的
UIViewController *vc = self.navigationController.viewControllers[0];
[self.navigationController popToViewController:vc animated:YES];
}
#pragma mark --- leftBarButtonAction: ---
// 返回到上一个界面(上一个视图控制器)
// 最常用的方法: 一级一级的跳 一级一级的返回
- (void)leftBarButtonAction:(UIBarButtonItem *)barButton
{
[self.navigationController popViewControllerAnimated:YES];
}
//如果哪一个控制器不想要导航栏 可以直接将导航栏隐藏
self.navigationController.navigationBarHidden = YES;
二 界面传值
1.属性传值,从前往后传,在界面跳转的瞬间将值传过去,就是在界面跳转的方法中去实现传值,从后往前传需要代理传值或Block传值
》先在后一个视图控制器中创建需要传输的属性
#pragma mark --- rightBarButtonAction ---
- (void)rightBarButtonAction:(UIBarButtonItem *)barButton
{
SecondViewController *secondViewVc = [[SecondViewController alloc]init];
// 第二个界面的字符串 接收本类输入框的值
// 从前往后传值 属性传值
secondViewVc.string = _textField.text;
// 第一个界面 成为第二个界面的代理
// 用于从后往前传值 代理传值
secondViewVc.delegate = self;
//secondViewVc.string = _textField.text;
[self.navigationController pushViewController:secondViewVc animated:YES];
[secondViewVc release];
}
#pragma mark --- changeText ---
- (void)changeText:(NSString *)string
{
self.textField.text = string;
}
// 第二个界面发起一个协议
// 协议中的方法由第一个界面去执行
// 让代理去执行 协议方法的时候 我们需要 把第二个界面(本类)的输入框值 传回去
@protocol secondVcDelegate <NSObject>
- (void)changeText:(NSString *)string;
@end
@interface SecondViewController : UIViewController
// 接收第一个界面输入框的值
// 然后再赋值给 本类的输入框值
@property (nonatomic,copy)NSString *string;
@property (nonatomic, assign)id<secondVcDelegate>delegate;
@end
//下一个界面接收传过来的值
self.textField = [[UITextField alloc]initWithFrame:CGRectMake(100, 100, 100, 30)];
self.textField.borderStyle = UITextBorderStyleRoundedRect;
// 此时此刻的string 已经接收了 第一个界面输入框的值
// 现在把这个值 赋值给 本类的输入框
self.textField.text = self.string;
[self.view addSubview:_textField];
[_textField release];
//代理传值,在界面跳转的方法中
#pragma mark ---leftBarButtonAction---
- (void)leftBarButtonAction:(UIBarButtonItem *)barButton
{
if ([self.delegate respondsToSelector:@selector(changeText:)])
{
// 第二个界面的字符串 接收本类输入框的值
// 从前往后传值 利用属性传值
[self.delegate changeText:_textField.text];//代理实现协议方法,注意参数
}
[self.navigationController popViewControllerAnimated:YES];
}
//注意协议传值的7个步骤,第一个控制器要接收协议,切记此时在引入的头文件要和协议同时在.m或者.h中