Navigation:导航控制器
导航控制器的作用:继承自UIViewController,以栈的方式管理视图控制器。
栈:相当于一个数组,每个视图控制器放入数组中,后进先出的顺序出入栈。每次屏幕上只显示位于栈顶端的视图。导航控制器所控制的视图控制器之间是主细关系(分层关系)。
导航控制器的根视图:位于栈底的一个视图控制器,其特点是可被代替但不可被弹出。
**根视图的设置
- (id)initWithRootViewController:(UIViewController *)rootViewController;
(UIViewController *)rootViewController:设置此视图控制器为根视图,存在栈底
**单个视图的入栈(压栈)
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
(UIViewController *)viewController:要入栈的视图控制器
(BOOL)animated:入栈时是否有动画效果
**单个视图的出栈(弹栈)
- (UIViewController *)popViewControllerAnimated:(BOOL)animated;
(BOOL)animated:对当前视图弹栈时是否显示动画
该方法将返回弹出的视图控制器
**多个视图的入栈(压栈)
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated;
(NSArray *)viewControllers:将想要入栈的视图存入一个数组中从最后一个元素开始顺序入栈,只显示数组中firstObject因为他在栈的最顶端
(BOOL)animated:入栈时是否有动画效果
**多个视图的出栈(弹栈)
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL);
(UIViewController *)viewController:显示此视图,此视图控制器之上的视图被均弹出
animated:(BOOL):对当前视图显示时是否显示动画
该方法将被弹出的视图存入一个数组中,栈中顶端的视图在数组的第一个,以此类推
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;
(BOOL)animated:对当前视图显示时是否显示动画
该方法将根视图以外的视图全部弹出存入一个数组中,栈中顶端的视图在数组的第一个,以此类推
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
导航控制器的设置:
- 设置四个视图控制器AViewController BViewController CViewController DViewController
- AViewController*avc=[[AViewController alloc]init];//初始化A视图
- UINavigationController*nc=[[UINavigationController alloc]initWithRootViewController:avc];//初始化nc,将A视图设为根视图
self.window.rootViewController=nc; - 在A中设置一个UITextField MyTextField1(设为属性) UIButton Mybutton1
在B中设置一个UITextField MyTextField2(设为属性) UIButton Mybutton2
在C中设置一个UITextField MyTextField3(设为属性) UIButton Mybutton3
在D中设置一个UITextField MyTextField4(设为属性) UIButton Mybutton4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
视图之间的传参:属性,单例,代理
**一般由主到细传值用属性传值(因为持有了细的对象)
**一般由细到主回传时用代理(因为没持有主的对象)
**单例可以来回传,但是因为单例在内存中永远存在占内存过多,所以一般不用单例(虽然细不持有主的对象但可以通过单例创建相同的对象)
属性传值:
A->B
将B的头包进A
#import "BViewController.h"
给Mybutton1写触发方法
-(void)passToB:(UIButton*)sender
{
BViewController*bvc=[[BViewController alloc]init];//在A上初始化B
[self.navigationController pushViewController:bvc animated:YES];//B入栈
//通过属性 因为A已持有B的实例所以可以拿到B的属性(这里是要把输入框写成属性的原因)
bvc.Myfield2.text=self.Myfield1.text;//将A的值传给B
}
单例传值:
B->A
将A的头包进B
#import "AViewController.h"
通过B来改A的值,则B需要拿到A的对象,但B并不持有A,若在B上初始化A获得的是一个新的对象,所以要将A写为单例,这样通过单例方法创建的对象都是同一个对象(指相同一块内存)
$$要改谁的值将谁设成单例$$
static AViewController* avc;
+(AViewController*)Avvc
{
if (!avc)
{
avc=[[AViewController alloc]init];
}
return avc;
}
给Mybutton2写触发方法
-(void)passToA:(UIButton*)sender
{
[self.navigationController popViewControllerAnimated:YES];
AViewController*avc=[AViewController Avvc];//通过单例方法创建A
avc.Myfield1.text=self.Myfield2.text;//将B的值传给A
}
协议传值:
B->A
B不持有A的对象所以要用协议来让A作为B的代理来改自己的值
B想做的事做不了,就将想做的事写成方法(协议),就让A(代理)去做
改谁的值,谁做代理
这里
- 在B上设置协议 @protocol Passtxt <NSObject>//第B页定义一个协议
-(void)changeValue:(NSString*)txt;//参数代表想要通过B传回给A的数据
@end - 在B上定义一个属性存代理对象
@property(assign,nonatomic)id<Passtxt>delegate;//指定代理 - 在A上将B的头加上#import"BViewController.h"并且加上<Passtxt>标示其遵守此协议
- 在A的.h上实现此方法 -(void)changeValue:(NSString*)txt
{
self.Myfield1.text=txt;//值赋给A} - 在A上指定其为代理(在A上B初始化的地方指定A为代理):
在A将B入栈的方法中添加以下语句
bvc.delegate=self;
-(void)passToB:(UIButton*)sender
{
BViewController*bvc=[[BViewController alloc]init];//在A上初始化B
[self.navigationController pushViewController:bvc animated:YES];//B入栈
//通过属性 因为A已持有B的实例所以可以拿到B的属性(这里是要把输入框写成属性的原因)
bvc.Myfield2.text=self.Myfield1.text;//将A的值传给B
bvc.delegate=self; //设A为B的代理
}
6. 在B上通过代理调用A上的代理方法
-(void)passToA:(UIButton*)sender
{
[self.navigationController popViewControllerAnimated:YES];//将自己弹出栈
[self.delegate changeA:self.Myfield2.text];//通过协议改B值(此时的self.delegate指向A代表A)
}
B将自己的值作为参数传到方法中,方法在A上实现改自己的值