导航控制器
1. UINavigationController是导航控制器,是用来管理多个单视图控制器的控制器,此时它管理的多个单视图控制之间有一定得层级关系,(依赖关系,下一个页面的出现要依赖于上一个页面)。导航视图控制器创建时也会自带一个View只不过此时它的上面有两个子视图,一个是contentview,一个是navigationBar,管理的多个单视图控制器自带的View,都添加到contentview,导航控制器在完成页面间跳转的时候,是一个不断创建和销毁的过程
UINavigationController在管理视图的时候使用的栈的数据结构,进入下一界面入展,此时要创建下一级页面视图,返回上一级页面就是出栈,此时会把当前的视图界面给销毁
//创建单视图控制器
FirstViewController *firstVC = [[FirstViewController alloc]init];
// 创建导航控制器对象
// 将firstvc 指定为导航视图控制器的根视图的控制器
UINavigationController *navigationVC =[[UINavigationController alloc]initWithRootViewController:firstVC];
self.window.rootViewController = navigationVC;
[firstVC release];
[navigationVC release];
FirstViewController *firstVC = [[FirstViewController alloc]init];
// 创建导航控制器对象
// 将firstvc 指定为导航视图控制器的根视图的控制器
UINavigationController *navigationVC =[[UINavigationController alloc]initWithRootViewController:firstVC];
self.window.rootViewController = navigationVC;
[firstVC release];
[navigationVC release];
当界面的切换的时候,两个视图控制器A和B视图的现实和消失的过程
从A到B(从前到后)
A(ViewwilldisAppear)---》B(viewWillAppear)-->A(viewDiddisAppear:)--->B(viewDidAppear:)
从b到a从后到钱
从A到B(从前到后)
A(ViewwilldisAppear)---》B(viewWillAppear)-->A(viewDiddisAppear:)--->B(viewDidAppear:)
从b到a从后到钱
B(ViewwilldisAppear)---》A(viewWillAppear)-->B(viewDiddisAppear:)--->A(viewDidAppear:)
2.
//视图将要出现的时候触发
- (void)viewWillAppear:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);
}
//视图已近出现的时候
- (void)viewDidAppear:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);
}
//视图机将要消失
- (void)viewWillDisappear:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);
}
//视图已经消失的时候触发
- (void)viewDidDisappear:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);
}
- (void)viewWillAppear:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);
}
//视图已近出现的时候
- (void)viewDidAppear:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);
}
//视图机将要消失
- (void)viewWillDisappear:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);
}
//视图已经消失的时候触发
- (void)viewDidDisappear:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor orangeColor];
//调用配置导航条的颜色
[self configureCommonProperty];
// 调用界面导航条独有的
[self customNavigationItemAppearance];
UIButton *pusButton = [UIButton buttonWithType:(UIButtonTypeSystem)];
pusButton.frame = CGRectMake(20, 64, 280, 40);
[pusButton setTitle:@"进入下一个页面" forState:(UIControlStateNormal)];
[pusButton addTarget:self action:@selector(handlePush:) forControlEvents:(UIControlEventTouchUpInside)];
pusButton.backgroundColor = [UIColor redColor];
[self.view addSubview:pusButton];
}
3.
- (void)handlePush:(UIButton *)push
{
//2. 创建SecondViewController对象
SecondViewController *secondVC =[[SecondViewController alloc]init];
//3.获取导航视图控制器并完成跳转
//4.self.navigationController获取当前视图的导航控制器对象
//第一个参数:待跳转得视图控制器对象
//第二个参数:是否需要动画
[self.navigationController pushViewController:secondVC animated:YES];
//4.释放
[secondVC release];
NSLog(@"push");
}
//配置导航条公共的属性,该属性作用于所有的界面
- (void)configureCommonProperty
{
//设置导航条的颜色
self.navigationController.navigationBar.barTintColor = [UIColor yellowColor];
// 控制导航条的毛玻璃效果是否打开,影响的是contentview上视图的布局
self.navigationController.navigationBar.translucent = YES;
// 设置导航条是否隐藏
self.navigationController.navigationBarHidden = NO;
// 设置导航条内容的颜色(标题,视图边框的颜色)
self.navigationController.navigationBar.tintColor =[UIColor orangeColor];
//设置导航条的背景颜色
//44的高的图片只在导航条上 64高的时导航条和状态栏都有 其他情况拉伸或者压缩
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"1"] forBarMetrics:(UIBarMetricsDefault)];
}
4.
//针对于每个界面单独定制导航条上的内容
- (void)customNavigationItemAppearance
{
// 1. 配置导航条显示的标题
self.navigationItem.title = @"FirstVC";
// 2. 配置导航条的标题视图
UISegmentedControl *segmentView = [[UISegmentedControl alloc]initWithItems:@[@"所有通话",@"未接来电"]];
self.navigationItem.titleView = segmentView;
[segmentView release];
// 3.配置导航条的左右按钮
// 左
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithTitle:@"+" style:(UIBarButtonItemStylePlain) target:self action:@selector(handleLeftItem:)];
self.navigationItem.leftBarButtonItem = leftItem;
[leftItem release];
//右
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:(UIBarButtonSystemItemTrash) target:self action:@selector(handleRightItem:)];
self.navigationItem.rightBarButtonItem = rightItem;
}
#pragma mark 实现左barButton的方法
- (void)handleLeftItem:(UIBarButtonItem *)leftItem
{
NSLog(@"添加");
}
[super viewDidLoad];
self.view.backgroundColor = [UIColor orangeColor];
//调用配置导航条的颜色
[self configureCommonProperty];
// 调用界面导航条独有的
[self customNavigationItemAppearance];
UIButton *pusButton = [UIButton buttonWithType:(UIButtonTypeSystem)];
pusButton.frame = CGRectMake(20, 64, 280, 40);
[pusButton setTitle:@"进入下一个页面" forState:(UIControlStateNormal)];
[pusButton addTarget:self action:@selector(handlePush:) forControlEvents:(UIControlEventTouchUpInside)];
pusButton.backgroundColor = [UIColor redColor];
[self.view addSubview:pusButton];
}
3.
- (void)handlePush:(UIButton *)push
{
//2. 创建SecondViewController对象
SecondViewController *secondVC =[[SecondViewController alloc]init];
//3.获取导航视图控制器并完成跳转
//4.self.navigationController获取当前视图的导航控制器对象
//第一个参数:待跳转得视图控制器对象
//第二个参数:是否需要动画
[self.navigationController pushViewController:secondVC animated:YES];
//4.释放
[secondVC release];
NSLog(@"push");
}
//配置导航条公共的属性,该属性作用于所有的界面
- (void)configureCommonProperty
{
//设置导航条的颜色
self.navigationController.navigationBar.barTintColor = [UIColor yellowColor];
// 控制导航条的毛玻璃效果是否打开,影响的是contentview上视图的布局
self.navigationController.navigationBar.translucent = YES;
// 设置导航条是否隐藏
self.navigationController.navigationBarHidden = NO;
// 设置导航条内容的颜色(标题,视图边框的颜色)
self.navigationController.navigationBar.tintColor =[UIColor orangeColor];
//设置导航条的背景颜色
//44的高的图片只在导航条上 64高的时导航条和状态栏都有 其他情况拉伸或者压缩
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"1"] forBarMetrics:(UIBarMetricsDefault)];
}
4.
//针对于每个界面单独定制导航条上的内容
- (void)customNavigationItemAppearance
{
// 1. 配置导航条显示的标题
self.navigationItem.title = @"FirstVC";
// 2. 配置导航条的标题视图
UISegmentedControl *segmentView = [[UISegmentedControl alloc]initWithItems:@[@"所有通话",@"未接来电"]];
self.navigationItem.titleView = segmentView;
[segmentView release];
// 3.配置导航条的左右按钮
// 左
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithTitle:@"+" style:(UIBarButtonItemStylePlain) target:self action:@selector(handleLeftItem:)];
self.navigationItem.leftBarButtonItem = leftItem;
[leftItem release];
//右
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:(UIBarButtonSystemItemTrash) target:self action:@selector(handleRightItem:)];
self.navigationItem.rightBarButtonItem = rightItem;
}
#pragma mark 实现左barButton的方法
- (void)handleLeftItem:(UIBarButtonItem *)leftItem
{
NSLog(@"添加");
}
5.
//针对于每个界面单独定制导航条上的内容
- (void)customNavigationItemAppearance
{
// 配置导航条显示的标题
self.navigationItem.title = @"ThirdVC";
}
- (void)customNavigationItemAppearance
{
// 配置导航条显示的标题
self.navigationItem.title = @"ThirdVC";
}
//1.返回上一级界面,也是由导航视图控制器完成
//
// [self.navigationController popViewControllerAnimated:YES];
//
// NSLog(@"pop");
// 2. 返回到导航视图控制器的根视图控制器对象
// [self.navigationController popToRootViewControllerAnimated:YES];
//
// [self.navigationController popViewControllerAnimated:YES];
//
// NSLog(@"pop");
// 2. 返回到导航视图控制器的根视图控制器对象
// [self.navigationController popToRootViewControllerAnimated:YES];
// 3.
返回到指定的视图控制器##################################################
// 方法一
获取导航视图控制器的所有单视图控制器
NSArray *controllArray = self.navigationController.viewControllers;
//返回到指定的视图控制器
[self.navigationController popToViewController:controllArray[1] animated:YES];
//返回到指定的视图控制器
[self.navigationController popToViewController:controllArray[1] animated:YES];
方法二
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
//针对于每个界面单独定制导航条上的内容
- (void)customNavigationItemAppearance
{
// 配置导航条显示的标题
self.navigationItem.title = @"ForthVC";
}
- (void)customNavigationItemAppearance
{
// 配置导航条显示的标题
self.navigationItem.title = @"ForthVC";
}
##################对上面方法的总结#################
可以手动设置pop出栈,相当于删除这个页面,跳转到其他页面
//popViewControllerAnimated就是弹出,因为弹出只能弹出最上面的栈顶的那个,所以可以不用指定参数
//popToRootViewControllerAnimated-就是直接跳转到根视图控制图,如果只有两层,那么和popViewControllerAnimated并无区别,如果有很多层,那么其实就是相当于不仅把自己pop出去,还把所有除了根视图控制图之外的所有视图控制器都pop出去了,所以就相当于跳转到根视图控制器了
//popToViewController-就是跳转到指定的视图控制器xxx,这个xxx一定要在这个栈里面,即一定是在我们当前这个视图控制器的下面的,所以跳转也就是把自己和在xxx上面的所有视图控制器都pop出去,然后相当于直接跳转到xxx
//此处重点是这个xxx怎么获取,按照一般理解是用xxx再初始化一个视图控制器对象yyy,然后把这个对象yyy作为popToViewController参数
//但事实是,yyy是新初始化的,不在栈中,当然和在栈中的xxx初始化的那个对象也不是同一个对象,所以会报错(因为在栈中找不到啊)
//所以,self.navigationController.viewControllers出场,viewControllers是个数组,储存的时导航控制器栈中所有的视图控制器,最先push进去的时0,以此类推,最上面的肯定是数组的最后一个
//所以,那个xxx之前初始化的对象,可以用[self.navigationController.viewControllers objectAtIndex:0]表示,此处0就是根视图控制器
//所以,只要拿到navigationController,貌似能做很多事情
//popViewControllerAnimated就是弹出,因为弹出只能弹出最上面的栈顶的那个,所以可以不用指定参数
//popToRootViewControllerAnimated-就是直接跳转到根视图控制图,如果只有两层,那么和popViewControllerAnimated并无区别,如果有很多层,那么其实就是相当于不仅把自己pop出去,还把所有除了根视图控制图之外的所有视图控制器都pop出去了,所以就相当于跳转到根视图控制器了
//popToViewController-就是跳转到指定的视图控制器xxx,这个xxx一定要在这个栈里面,即一定是在我们当前这个视图控制器的下面的,所以跳转也就是把自己和在xxx上面的所有视图控制器都pop出去,然后相当于直接跳转到xxx
//此处重点是这个xxx怎么获取,按照一般理解是用xxx再初始化一个视图控制器对象yyy,然后把这个对象yyy作为popToViewController参数
//但事实是,yyy是新初始化的,不在栈中,当然和在栈中的xxx初始化的那个对象也不是同一个对象,所以会报错(因为在栈中找不到啊)
//所以,self.navigationController.viewControllers出场,viewControllers是个数组,储存的时导航控制器栈中所有的视图控制器,最先push进去的时0,以此类推,最上面的肯定是数组的最后一个
//所以,那个xxx之前初始化的对象,可以用[self.navigationController.viewControllers objectAtIndex:0]表示,此处0就是根视图控制器
//所以,只要拿到navigationController,貌似能做很多事情
属性传值
1.从前一个页面到后一个页面传值 葵花宝典 :属性传值
属性传值 的步骤:
第一步:在下一个视图控制器.h文件定义一个属性
第二步:在push之前将数据存储到属性中
第三步:取出属性中的值让控件显示
firstView secondView 这是两个单视图控制器
(1)#warning
属性传值第一步
定义属性,且属性的类型要和传人的数据类型保持一致在下一个.h中定义
也就是在secondView.h中定义属性
@property(nonatomic,copy)NSString *textString;
- (void)handleButton:(UIButton *)button
{
此时创建的是下一个界面对象
SecondViewController *secondVC = [[SecondViewController alloc]init];
(2)#warning 属性传值的第二步 push之前传人数据 在firstView.m中写
secondVC.
textString
= ((
UITextField
*)[
self
.
view
viewWithTag
:
200
]).
text
;
[
self
.
navigationController
pushViewController
:secondVC
animated
:
YES
];
[secondVC release];
}
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(20, 100, 280, 40)];
label.backgroundColor = [UIColor yellowColor];
label.text = @"给我上一个页面的内容";
(3)#warning 属性传值的第三步 取出数据让控件显示 在secondView.m中写
label.text = _textString;
[self.view addSubview:label];
[label release];
[super viewDidLoad];
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(20, 100, 280, 40)];
label.backgroundColor = [UIColor yellowColor];
label.text = @"给我上一个页面的内容";
(3)#warning 属性传值的第三步 取出数据让控件显示 在secondView.m中写
label.text = _textString;
[self.view addSubview:label];
[label release];
代理传值
1.从后一个页面往前一个页面传值 辟邪剑谱 :代理传值
代理传值的步骤:
第一步:制定协议
第二步:定义代理属性
第三步:在外界指定代理
第四步:代理要遵循协议
第五步:代理要实现协议中方法
第六步:让代理执行协议中的方法
firstView secondView 这是两个单视图控制器
(1)#warning 代理传值第一步 定义协议 在secondView.h中写
@protocol SecondViewControllerDelegate <NSObject>
@protocol SecondViewControllerDelegate <NSObject>
(2)#warning 代理传值第二步 定义代理属性 在secondView.h中写
@property
(
nonatomic
,
assign
)
id
<
SecondViewControllerDelegate
>delegate;
- (void)handleButton:(UIButton *)button
{
//此时创建的是下一个界面对象
SecondViewController
*secondVC = [[
SecondViewController
alloc
]
init
];
(3)#warning 代理传值的第三步 为后一个界面指定代理对象,只能是前一个视图控制器对象 在firstView.m中写
secondVC.
delegate
=
self
;
[self.navigationController pushViewController:secondVC animated:YES];
[secondVC release];
}
[secondVC release];
}
(4)#warning 代理传值的第四步 代理对象所在的类遵循协议 在firstView.m中写
@interface FirstViewController ()<SecondViewControllerDelegate>
@interface FirstViewController ()<SecondViewControllerDelegate>
(5)#warning
代理传值的第五步
实现协议中的方法 在firstView.m中写
-(void)passValue:(NSString *)string
{
((UILabel *)[self.view viewWithTag:300]).text = string
}
- (void)handlepopButton:(UIButton *)button
{
(6)#warning 代理传值的第六步 让代理执行协议中的方法
NSString
*string = ((
UITextField
*)[
self
.
view
viewWithTag
:
200
]).
text
;
if ([self.delegate respondsToSelector:@selector(passValue:)])
{
[self.delegate passValue:string];
}
[self.navigationController popViewControllerAnimated:YES];
}
单例传值
1.能从最后一个页面把值传到最前面 化功大法 :单例传值
单例传值的步骤:
第一步:定义单例类继承NSobject
第二步:定义单例类的创建方法
第三步:实现创建的方法
第四步:定义属性,存储传输数据,属性的类型和传输数据类型必须保持一致
第五步:给单例对象的属性赋值
第六步:取出单例的属性中存储的数据,赋值给控件
(1)#warning 单例传值的第一步 定义单例类继承NSobject 在自己重新创建的类.h中写
@interface SingleLeton : NSObject
(2)#warning 单例传值的第二步 定义单例类的创建方法 在自己重新创建的类.h中写
#################share stand main
创建单例对象方法一般常用的开头##################
+ (SingleLeton *)shareSingleLeton;
(3)#warning 单例传值的第三步 在自己重新创建的类.m中实现方法
//定义一个由static修饰的singLeton对象
//static修饰的变量的生命周期和应用程序的生命周期一样长,只有程序退出后台的时候才被销毁;单例多用在数据库中
static SingleLeton *single = nil;
+(SingleLeton *)shareSingleLeton
{
//single等于nil时还没有初始化,所以在if语句对其初始化
//实时同步单例对象的创建,保护其在多线程下的安全
@synchronized(self){
if (single == nil) {
single = [[SingleLeton alloc]init];
}
}
return single;
}
- (void)dealloc
{
self.string = nil;
[super dealloc];
}
//static修饰的变量的生命周期和应用程序的生命周期一样长,只有程序退出后台的时候才被销毁;单例多用在数据库中
static SingleLeton *single = nil;
+(SingleLeton *)shareSingleLeton
{
//single等于nil时还没有初始化,所以在if语句对其初始化
//实时同步单例对象的创建,保护其在多线程下的安全
@synchronized(self){
if (single == nil) {
single = [[SingleLeton alloc]init];
}
}
return single;
}
- (void)dealloc
{
self.string = nil;
[super dealloc];
}
(4)#warning 单例传值的第四步 定义属性,存储传输的数据,属性的类型要和传输数据保持一致 在自己重新创建的类.h中写
@property
(
nonatomic
,
copy
)
NSString
*string;
- (void)handleButton:(UIButton *)button
{
(5)#warning
单例传值的第五步
给单例对象的属性赋值 在单视图控制器的最后一个视图控制器.m中写
[SingleLeton shareSingleLeton].string = ((UITextField *)[self.view viewWithTag:200]).text;
[self.navigationController popToRootViewControllerAnimated:YES];
[self.navigationController popToRootViewControllerAnimated:YES];
}
这个一个方法视图将要出现的时候触发
-(
void
)viewWillAppear:(
BOOL
)animated{
(6)#warning
单例传值的第六步
取出单例中属性中存储的数据,赋值给控件 在单视图控制器的第一个视图控制器.m中写
((
UILabel
*)[
self
.
view
viewWithTag
:
300
]).
text
= [
SingleLeton
shareSingleLeton
].
string
;
}