=========================界面间通讯======================
界面间的值传递分为三种,属性值传递、代理值传递、单例值传递
界面的搭建,分为三个视图控制器,上面分别有 UILabel、UITextField、UIButton三个空间,
主要目的,
①,实现FirstVC的UITextField的值在切换到SecondVC的时候传递给SecondVC的UILabel上//属性传值
②,实现SecondVC上的UITextField的值在切换回FirstVC的时候传递给FirstVC的UILabel上//代理传值
③,实现FirstVC上的UITextField的值直接传递给ThirdVC的UILabel上//单例传值
创建FirstVC界面 后面两个界面跟这个一样
#import "FirstViewController.h"
#import "SecondViewController.h"
#import "Singlleton.h"
#warning 代理传值第四步 代理对象遵循协议
@interface FirstViewController ()<SecondViewControllerDelegate>
@property (nonatomic,retain)UILabel *label;
@property(nonatomic,retain)UITextField *textField;
@property(nonatomic,retain)UIButton *button;
@end
@implementation FirstViewController
//懒加载
- (void)dealloc
{
[_label release];
[_textField release];
[super dealloc];
}
-(UILabel *)label{
if (_label ==nil) {
_label = [[UILabel alloc]initWithFrame:CGRectMake(50, 104, 200, 40)];
}return _label;
}
-(UITextField *)textField{
if (_textField ==nil) {
_textField =[[UITextField alloc]initWithFrame:CGRectMake(50, 164, 200, 40)];
}return _textField;
}
-(UIButton *)button {
if (_button ==nil) {
_button =[UIButton buttonWithType:(UIButtonTypeSystem)];
}return _button;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor cyanColor];
//添加到视图
[self.view addSubview:self.label];
self.label.backgroundColor = [UIColor greenColor];
//添加到视图
[self.view addSubview:self.button];
//添加到视图
[self.view addSubview:self.textField];
self.textField.backgroundColor =[UIColor yellowColor];
self.textField.clearsOnBeginEditing = YES;
[self makeButton];
}
//布局
-(void)makeButton{
self.button .frame = CGRectMake(50, 224, 200, 40);
self.button.backgroundColor = [UIColor redColor];
[self.button setTitle:@"进入下一个页面" forState: UIControlStateNormal];
[self.button addTarget:self action:@selector(handleButton:) forControlEvents:UIControlEventTouchUpInside];
}
#pragma mark-----button 点击事件-------
-(void)handleButton:(UIButton *)sender{
//进入下一个视图的步骤
// 1.创建第二个视图 并引入
SecondViewController *secondVC= [[SecondViewController alloc]init];
#warning 属性传值第二步, push 之前传入数据
secondVC.text = self.textField.text;
#warning 代理传值 第三步 为后一个页面指定代理对象为
secondVC.delegate = self;
#warning 单例传值的第四步 在 push 之前 textField 里面一定会有值除非你不写 将输入的数据存储到单例对象的属性 text 中
[Singlleton shareSinglleton].text = self.textField.text;
// 2.通过导航控制器进入下一个界面
//得到自身坐在的多视图控制器(UINavigationController)
[self.navigationController pushViewController:secondVC animated:YES];
[secondVC release];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#warning 代理传值第五部 实现协议中的方法 要干的活
-(void)passValue:(NSString *)text{
self.label .text=text;
}
//代码略。
@end
1.属性传值:
第一步,在SecondViewController的.h文件中声明一个NSString类型的变量text,用来接受FirstViewController传递过来的值。
#warning 属性传值的第一步,定义属性
@property (nonatomic,retain)NSString *text;
第二步,在FirstViewController类的.m文件中的button调用的方法(push进SecondViewController之前)内,将FirstViewController中的UITextField的text属性的值传给SecondViewController创建出来的secondVC的text中
#warning 属性传值第二步, push 之前传入数据
secondVC.text = self.textField.text;
//self代表firstVC
第三步,在SecondViewController类的.m文件中的布局UILabel的方法中接受SecondViewController的text值
#warning 属性传值第三步 取出数据 给控件赋值
self.label.text = self.text;
// self代表secondVC
2.代理传值:
因为secondVC马上就要被删除了,所以不能通过属性来传值,我们可以通过设置代理来将其中的值传递给FirstVC
第一步,定制协议,在SecondViewController类的.h中定制协议
#warning 代理传值的第一步,定义协议
@protocol SecondViewControllerDelegate <NSObject>
-(void)passValue:(NSString *)text;
//前提SecondViewController中还是要有text这个实例变量
@end
第二步,定义代理属性,在SecondViewController类的.h文件中写一个属性
#warning 代理传值第二步, 属性 用来存储外界传进来的代理对象
@property (nonatomic,assign)id<SecondViewControllerDelegate>delegate;
//delegate 只是一个名字你可以取其他的 但是下面再使用的时候 要用你新定的名字
第三步,指定代理对象,在FirstViewController的.m文件中的button的响应方法(创建secondVC对象的地方指定代理)中
#warning 代理传值 第三步 为后一个页面指定代理对象为
secondVC.delegate = self;//self代表FirstVC
第四步,遵循协议,在FirstViewController的.m文件中遵循协议,遵循协议的位置为:
#warning 代理传值第四步 代理对象遵循协议
@interface FirstViewController ()<SecondViewControllerDelegate>
@end
第五步,实现协议方法,在FirstViewController的.m文件中实现协议中的方法
#warning 代理传值第五部 实现协议中的方法 要干的活
-(void)passValue:(NSString *)text{
self.label .text=text;
}
//self代表FirstVC,text中是SecondVC中UITextField的值
第六步,让代理完成方法的时机,在SecondViewController类的.m文件中,在调回上一个页面的方法前就是pop前
-(void)handleButton:(UIButton *)sender{
#warning 代理传值第六步 让代理实现协议中的方法
//首先判断代理有没有实现协议中的方法 在 pop 之前让代理干活
if ([self.delegate respondsToSelector:@selector(passValue:)]) {
//这是要做的事
[self.delegate passValue:self.textField.text];
//上面的内部实现
/*
{
self.label.text = text;
2.= text 等于 self.textField text;
}
*/
}
[self.navigationController popViewControllerAnimated:YES];
}
//self代表 secondVC self.delegate代表FirstVC 重点
3.单例传值,思想让一个视图控制器中的值存在一个单独出来的类中,这个类有且只有这一个对象,所有的有层级关系的是同控制器都可以访问这个类里的数据
特点:
/*
1.类方法
2.单例创建的对象是同一个
3.内部创建了实例对象 ,并且不能被释放
*/
第一步,定义单例类,创建一个机遇NSObject类的子类Singleton
第二步,定义一个单例的方法,只能是类方法,在Singleton类的.h文件中声明一个类方法
+ (Singleton *)shareSingleton;
第三步,定义一个单例属性,存储传输的数据在
#import <Foundation/Foundation.h>
# warning 单例传值的第一步 定义一个单例类
@interface Singlleton : NSObject
#warning 单例传值第二步 定义一个单例的方法 只能是类方法
+(Singlleton *) shareSinglleton;
#warning 单例传值第三步 定义一个单例属性 目的存储传输的数据
@property (nonatomic,copy)NSString *text;
@end
在Singleton类的.m中写以下内容
#import "Singlleton.h"
//存在静态区 静态区的程序 只要运行就不会被释放
@implementation Singlleton
static Singlleton *single = nil;
+(Singlleton *) shareSinglleton{
//同步操作 保证在多线程中安全
@synchronized(self){
//控制该类只能设置一个对象
if (!single) {
single = [[Singlleton alloc]init];
}return single;
}
}
- (void)dealloc
{
[_text release];
[super dealloc];
}
@end
第四步,将firstVC的UITextField的值赋值给Singleton的text,在FirstViewController类的.m文件中的 push之前(跳转页面之前)
#warning 单例传值的第四步 在 push 之前 textField 里面一定会有值除非你不写 将输入的数据存储到单例对象的属性 text 中
[Singlleton shareSinglleton].text = self.textField.text;
//self代表FirstVC
第五步,将FirstVC中的UITextField的值传递给ThirdVC中的UILabel,在Thi人的ViewController类的.m文件中的viewDidLoad方法中
#warning 单例传值的第五步 从单例对象中 取出属性所存储的数据 给 third 赋值
self.label.text = [Singlleton shareSinglleton].text;//self代表ThirdVC
传值总结:/*
1.无论是那种传值 一定要赶在 push 之前 如果走了 push 那当前的界面就会进入后台 你就没有机会传值了
*/