UINavigationController是UI中很常用的管理多个控制器之间跳转的控制器,叫导航控制器
一、UINavigationController概念
1.将UINavigationController作为window的根视图控制器(rootViewController)
2.给UINavigationController一个控制器用于显示(UIViewController)
// 将UINavigationController设为window的根视图控制器
// 并将OneViewController的对象设为UINavigationController的根视图控制器
self.window.rootViewController = [[[UINavigationController alloc] initWithRootViewController:
[[OneViewController new] autorelease]] autorelease];
3.UINavigationController的tag来控制每个控制器(UIViewController)之间的切换
4.导航控制器(UINavigationController)永远都不只是它自己表示,可以包含多个控制器(UIViewController)
5.导航控制器(UINavigationController)是以“栈”的方式对多个控制器进行管理(先进后出,后进先出,内存管理机制,不会的同学,请问度娘)
6.导航控制器(UInavigationController)只有一个根视图控制器(rootViewController)但可以有多个子控制器(任何继承自UIViewController的类(多态),都可以作为根视图控制器)
7.必须要给每一个控制器设置“title”属性
#pragma mark - 重写
#pragma mark 设置自定义视图
- (void)loadView
{
self.firstView = [[FirstView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.view = _firstView;
self.title = @"第一页";
[_firstView release];
}
二、UINavigationController工作原理
1.viewControllers属性获取“栈”中所有管理的控制器
2.navigationController属性,是“栈”中所有的控制器,通过该属性获取导航控制器对象(UINavigationController)
[self.navigationController pushViewController:secondVC animated:YES];
三、控制器之间跳转方法(入栈和出栈)
1.pushViewController:animated // 进入下一个视图控制器
- (void)buttonAction:(UIButton *)sender
{
// 跳转页面初始化
SecondViewController *secondVC = [[[SecondViewController alloc] init] autorelease];
// 获取输入框的内容,并赋值给第二个控制器的propertyValue属性
secondVC.propertyValue = _firstView.textFiled.text;
// 推出
[self.navigationController pushViewController:secondVC animated:YES];
}
2.popViewControllerAnimated // 返回上一个视图控制器
3.popToViewController:animated // 返回到指定的视图控制器
- (void)buttonAction:(UIButton *)sender
{
FirstViewController *firstVC = self.navigationController.viewControllers[0];
[self.navigationController popToViewController:firstVC animated:YES];
}
这里需要注意的是popToViewController:animated的参数 不能是新new出来的控制器,需要通过viewControllers属性得到要跳转的控制器对象。
4.popToRootViewControllerAnimated // 返回到根视图控制器
四、控制器常用属性
1.viewControllers // 取得所有处于栈中的控制器
2.topViewController // 取得位于栈顶的控制器
3.visibleViewController // 取得当前正在显示的控制器
4.navigationBar // 导航条
五、控制器之间的传值
第一种:通过参数传值
假如A控制器跳转到B控制器,将A控制的值传递到B控制器中,我们要在B控制器的.h文件中追加变量
#import <UIKit/UIKit.h>
@interface PhotoDetailViewController : UIViewController
@property (nonatomic, assign) NSInteger index;
@end
然后在跳转的事件中,给B控制器的属性赋值,从而达到控制器之间的传值(
注:只能单向从前往后传值)
#pragma mark - 点击图片事件
- (void)buttonAction:(UIButton *)sender
{
// 创建控制器
PhotoDetailViewController *photoDetaiVC = [[PhotoDetailViewController new] autorelease];
// 传值
photoDetaiVC.index = sender.tag % 1000;
// 跳转
[self.navigationController pushViewController:photoDetaiVC animated:YES];
}
第二种:使用代理模式传值(B传值给A)
代理回调机制
1.被代理类(B)声明协议
// 1.被代理类声明协议
@protocol SecondViewControllerDelegate <NSObject>
// 声明协议方法,用来传值使用
- (void)getValue:(NSString *)str;
@end
2.被代理类(B)声明代理属性
@interface SecondViewController : UIViewController
@property (nonatomic, copy) NSString *propertyValue;
// 2.声明代理属性
@property (nonatomic, assign) id <SecondViewControllerDelegate> delegate;
@end
3.让代理执行协议方法
#pragma mark - 按钮点击事件
- (void)buttonAction:(UIButton *)sender
{
// 3.让代理执行协议方法
// 查看代理类(A)是否执行了此方法
if ([_delegate respondsToSelector:@selector(getValue:)]) {
// 将页面上的输入框的值,作为参数
[_delegate getValue:_secondView.textFiled.text];
}
FirstViewController *firstVC = self.navigationController.viewControllers[0];
[self.navigationController popToViewController:firstVC animated:YES];
}
4.在A控制器的按钮点击事件中,设置当前控制器( A)对象,为B控制器的代理
#pragma mark - 按钮点击事件
- (void)buttonAction:(UIButton *)sender
{
// 跳转页面初始化
SecondViewController *secondVC = [[[SecondViewController alloc] init] autorelease];
// 4.设置当前控制器对象,为第二个页面的代理
secondVC.delegate = self;
// 获取输入框的内容,并赋值给第二个控制器的propertyValue属性
secondVC.propertyValue = _firstView.textFiled.text;
// 推出
[self.navigationController pushViewController:secondVC animated:YES];
}
5.在A控制器中遵守B控制器的协议
// 5.遵守B控制器的协议
@interface FirstViewController () <SecondViewControllerDelegate>
@property (nonatomic, retain) FirstView *firstView;
@end
6.在A控制器中实现协议方法,完成传值
// 6.实现协议方法,完成传值
- (void)getValue:(NSString *)str
{
// 将参数的值给当前页面的输入框
_firstView.textFiled.text = str;
}
执行原理:在A控制器调用按钮点击事件的时候,设置A控制器为B控制器的代理者,A控制器遵守协议并实现协议方法(未执行此方法),当B控制器按钮点击事件触发时,我们判断A控制器是否实现了B控制器的协议方法,如果实现,让A控制器执行协议方法,并完成传值。这就是代理回调机制
控制器之间传值工程链接: http://pan.baidu.com/s/1bnGu0wR 密码: q7f6
针对导航控制器的使用方法,我也做了一个模仿相册的工程,画面效果做得比较次,大家只看实现机制就好哈
导航控制器工程链接: http://pan.baidu.com/s/1jGtL3k6 密码: f3pf