UI页面跳转和传值

来源:互联网 发布:基于stack的列表 java 编辑:程序博客网 时间:2024/05/28 20:19

一、页面跳转:

利用navigation实现跳转和利用模态跳转的区别:
navigation实现跳转,始终在同一窗口,由导航栏来管理不同的viewController的加载和退出,因此导航栏始终在。
模态实现跳转,是新建一个窗口,如果需要新的窗口也具有导航栏,那么要重新设置导航栏。

二、传值

在从view1跳转到view2的前提下,根据传值的方向可划分为两种情况:

情况一:从view1传值到view2

这样种情况下,view2是由view1创建的,view1获得了对view2的引用,自热也可以访问view2的属性。因此,view1要传值传给view2就直接修改view2的属性值就可以了。

情况二:从view2传值回view1

由于是从view1跳转到view2,view2不能得到view1的引用,因此不可以通过直接修改view1的属性来把自己的值传给view1。这时候就需要用到代理模式来实现传值了。也就是说,既然view2不能亲自修改view1的变量,那view2就叫view1自己修改。实现这种思想的办法有3种,以下一一介绍。

(1)利用代理模式传值

代理模式的思路是:作为委托方的类负责制定协议,并且委托方的类需要有一个表示代理人的属性delegate。任何遵守了协议的类都可以作为该协议的代理方。

代理模式的实施:首先要为作为代理方的对象指定一个对象作为其代理人,也就是给这个对象的delegate属性赋值,接着委托人就可以向代理对象发出指令,让代理人调用它实现的协议相关方法来实施工作。
特点,方法实现的位置在代理方的类,因此在方法中可以获取和修改代理方的实例变量。因此,委托方可以利用这一点,差遣代理方修改代理方的属性。

回到传值的话题上,如果需要将view2的值传回到view1,也就是view2需要改变view1某个实例变量的值,此时,view2应该作为委托方,view1作为代理方。这样在view2回到view1之前,就可以叫view1调用其实现的方法来保存好这个要传的值。当然实现这一步的前提是已经将view1确定为view2的delegate。那么在view2不能获取对view1的引用的情况下又怎么将view1确定为view2的delegate呢?其实很简单,虽然view2获取不了view1的引用,但是view1可以获取view2的引用,那么只要在view1跳转到view2之前,让view1把自己设为view2的代理就可以了。(在下面第(4)点给出这个方法的例子)。

(2)利用block传值

利用block传值的关键在于,将block的定义和block的实现分开,这与代理模式有异曲同工之妙。代理模式就是将方法的声明(委托方指定的协议)和方法的实现(代理完成具体的方法实现)分开。

与方法的实现类似,在block的具体实现中也可以获取到其所在环境的实例变量和对象,因此,利用这一点,引用了这个block的类就可以修改block所在环境的属性值。

在传值的时候,如果要将view2的值传回到view1,也就是view2需要改变view1某个实例变量的值,因此block应该在view1中实现,而view2要获得对这个block的引用(通常以属性的方式),以便可以调用它。那么只要保证在从view1跳转到view2之前,把view1中实现的block的引用先传给了view2,那么在view2跳转回view1的时候,就可以调用这个block来把view2的值传给view1了。(在下面第(5)点种给出这个方法的例子)

(3)利用方法回调block传值

这个方法和利用block传值的原理其实一样,就是把block的定义和block的实现分开,区别就在于,block的定义不是以一个属性的形式存在于view2中,而是作为view2的一个方法的参数,而block的实现是在view1中调用view2的这个方法时给出。这样的好处有两个:一是传值的命令是在view1中发出的,只要创建了view2对象,就可以通过调用view2的方法进行传值,与是否跳转到view2无关。二是在方法中可以实现双向传值(具体看例子)。(在下面第(6)点种给出这个方法的例子)

(4)代理传值的例子:

从view1跳转到view2,再从view2回到view1时,把view2的背景颜色传给view1,并且改变view1的背景颜色。

1.首先是方法的定义(协议的定义):

view2中定义协议,协议中有一个方法,用来改变代理view的背景色

@protocol getColor<NSObject>-(void)setBgColorToColorFromDelegte:(UIColor *)color;@end

view2还需要有一个遵守该协议的代理

@interface SenconViewController : UIViewController<UITextFieldDelegate>@property (nonatomic,retain)id <getColor> delegate;@end

2.方法的实现(代理遵守协议)

让view1遵守协议

@interface FirstViewController : UIViewController<getColor>@end

并实现协议方法

-(void)setBgColorToColorFromDelegte:(UIColor *)color{    self.view.backgroundColor=color;}

3.方法的调用(设置代理,差遣代理,实现传值)

在从view1跳转到view2的之前将view2的代理设置为view1

view2.delegate=self;[self.navigationController pushViewController:view2 animated:YES];

在view2中调用代理(也就是view1)的方法,更改view1的背景色

[self.delegate setBgColorToColorFromDelegte:self.view.backgroundColor];

(5)block传值的例子

同样是在view2的背景色传给view1,并设置view1的背景色为相同的颜色。

1.方法的定义(block的定义)

view2中定义block属性:

@property (nonatomic,copy)  void(^functionBlock)(UIColor *color);

2.方法的实现(block的实现)

view1跳转到view2之前,给出block的实现:

 view2.functionBlock=^(UIColor *color){        self.view.backgroundColor=color;    };[self.navigationController pushViewController:view2 animated:YES];

3.方法的调用(调用block实现传值)

在view2中调用block,改变view1的背景色:

-(void)viewWillDisappear:(BOOL)animated{    _functionBlock(self.view.backgroundColor);}

(6)方法回调block传值的例子

根据view1传过来的Bool值来决定是否将view2的背景色传给view1。

1.block的定义及调用(block所在方法的定义及实现)

在view2中定义一个带block参数的方法:

-(void)setChangeBgColorOrNot:(BOOL)change UsingBlock:(ChangeColorBlock )block;

实现该方法

-(void)setChangeBgColorOrNot:(BOOL)change UsingBlock:(ChangeColorBlock )block{    if (changeOrNot==YES) {        block(self.view.backgroundColor);    }}

2.block的实现(block所在方法的调用)

在view1中,调用view2的方法,并提供block的实现:

[view2 setChangeBgColorOrNot:YES UsingBlock:^(UIColor * color){    self.view.backgroundColor=color;}];

这就实现了双向传值。

0 0
原创粉丝点击