OC控制器之间的传值

1.正向传值

属性传值
在B类中定义属性用于接收A类传来的数据

2.反向传值(回调)

1)利用对象反向传值

将A类对象定义成B类的属性进行传值
如,通过KGSubViewController(B)修改 KGRootViewController(A)的Label
KGRootViewController

//在KGRootViewController中定义函数接收返回的数据
-(void)backValue:(NSString *)string color:(UIColor *)color{ 
//将参数的值赋给
      label label.text = string; 
//将颜色赋给赋给lable的字体颜色 
      label.textColor = color;
}

界面跳转至KGSubViewController,并将KGRootViewController对象传到KGSubViewController中

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
KGSubViewController * svc = [[KGSubViewController alloc]init]; 
  //让B持有A
      svc.rvc = self;
      [self presentViewController:svc animated:YES completion:nil];
}

KGSubViewController
//创建一个Root对象@property(nonatomic,retain) KGRootViewController * rvc;//在销毁之前,做一些回传数据的事-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [self.rvc backValue:tf.text color:[UIColor redColor]]; [self dismissViewControllerAnimated:YES completion:nil];}
2)使用TargetAction反向传值

通过指定回传方法和回传对象进行传值
仍以上例为例,实现方法为:

KGRootViewController
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
      KGSubViewController * svc = [[KGSubViewController alloc]init]; 
//将回传对象进行指定 svc.target = self; 
//这里的self是指rootviewcontrller 
//将回传方法,进行指定 
      svc.selector = @selector(backValue:);
      [self presentViewController:svc animated:YES completion:nil];
}
-(void)backValue:(NSString *)string{ 
      //回传数据方法
      label.text = string;
}

KGSubViewController
//在这里定义两个属性,用来接收目标和方法,用来进行反向传值//接收要回传的对象
@property(nonatomic,retain) id target;
 //接收回传数据的方法
@property(nonatomic,assign) SEL selector;
//在销毁之前,将数据回传回去
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
//利用保存的target 和 action 来进行回传 
      if ([self.target respondsToSelector:self.selector]) { 
          [self.target performSelector:self.selector withObject:tf.text]; 
      } 
      [self dismissViewControllerAnimated:YES completion:nil];
}
3)使用协议代理反向传值

协议代理是回调中常用的方法,顾名思义,把某个对象要做的事情委托给别的对象去做。那么别的对象就是这个对象的代理,代理它来打理要做的事情。使用协议代理不仅可以正向传值,亦可反向传值。在使用中,需要注意哪个类是委托方,哪个类是代理方。总之:谁传值谁是委托方
如,通过KGSubViewController改变KGRootViewController中label值
在KGSubViewController页面里,制定一个协议

@protocol BackValue
//回传数据的协议方法
-(void)backValue:(NSString *)string;@end@property(nonatomic,retain) id < BackValue > delegate;

在KGSubViewController使代理方实现方法

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
//代理方实现协议中的方法 
      [self.delegate backValue:tf.text]; [self dismissViewControllerAnimated:YES 
      completion:nil];
}

在KGRootViewController中实现协议

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ KGSubViewController * svc = [[KGSubViewController alloc]init]; //让A同意B所提出的协议条件 svc.delegate = self; [self presentViewController:svc animated:YES completion:nil];}//实现协议 方法-(void)backValue:(NSString *)string{ label.text = string;}
4)使用系统自带的Block进行反向传值

block是代码块的对象,类似函数指针,调用block如同调用代码块中的代码,利用block可以实现回调。
在系统提供方法中,有很多使用block方法,如界面跳转presentViewController时
将KGRootViewController中label.text值传给KGSubViewController textField.text

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ KGSubViewController * svc = [[KGSubViewController alloc]init]; svc.rvc = self; //OC中,block用来去指向一个匿名的语句块,从而可以当成函数还调用该语句块 //这个方法的第三个参数是一个block,意思说,当弹出来的svc显示完成后,执行block里的内容 [self presentViewController:svc animated:YES completion:^{ //正向传值 svc.textField.text = self.label.text; }];}

将KGSubViewController textField.text值传给 KGRootViewController中label.text
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [self dismissViewControllerAnimated:YES completion:^{ self.rvc.label.text = self.textField.text; }];}
5)使用自定义Block反向传值
KGSubViewController
//定义一个block的属性@property(nonatomic,copy)void (^block)(NSString *);-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ //执行block self.block(tf.text); [self dismissViewControllerAnimated:YES completion:nil];}

KGRootViewController
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ KGSubViewController * svc = [[KGSubViewController alloc]init]; //给block赋值,做用是让svc知道block指向的代码块的功能 svc.block = ^(NSString * string){ label.text = string; }; [self presentViewController:svc animated:YES completion:nil];}

*3.双向产值*1)使用NSUserDefaults进行数据传值
NSUserDefaults纪录本地一些轻量级的数据,是单例类。其通过userDefaults对象来将选中按钮的索引给保存到NSUserDefaults的plist文件中。这个文件实际上是一个plist文件,在沙盒中的/Library/Preferences/NSUserDefaults.plist 这个位置
当KGSubViewController调用viewWillAppear时读取沙盒内容
-(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; //获取NSUserDefaults文件,读取里面内容,来决定让哪一个按钮进行选中 NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; //通过存的时候的key值来进行取值 NSString * value = (NSString *)[ud objectForKey:@"ButtonIndex"]; //计算出按钮的tag值 int buttonIndex = 1000 + value.intValue; //利用tag值取到按钮 UIButton * button = (UIButton *)[self.view viewWithTag:buttonIndex]; button.selected = YES;}

KGRootViewController点击button将点击按钮的索引存入沙盒中
-(void)buttonClick:(UIButton *)button{ for (int i = 1;i<6; i++) { UIButton * btn = (UIButton *)[self.view viewWithTag:1000+i]; if (btn.selected == YES) { btn.selected = NO; } } button.selected = YES; //将每次点击选中的按钮索引给存起来 NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults]; NSLog(@"%@",[NSBundle mainBundle]); //通过userDefaults对象来将选中按钮的索引给保存到NSUserDefaults的plist文件中 //这个文件实际上是一个plist文件,在沙盒中的/Library/Preferences/NSUserDefaults.plist 这个位置 [userDefaults setObject:[NSString stringWithFormat:@"%d",button.tag - 1000] forKey:@"ButtonIndex"]; //回写文件 [userDefaults synchronize]; //synchronize:使同步,同时发生}

KGRootViewController
-(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; //获取NSUserDefaults文件,读取里面内容,来决定让哪一个按钮进行选中 NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; //通过存的时候的key值来进行取值 NSString * value = (NSString *)[ud objectForKey:@"ButtonIndex"]; label.text = [NSString stringWithFormat:@"上次按下的是第 %@ 个按钮",value];}

2)使用系统的UIApplication单例进行传值
单例类在程序中只创建一次实例对象,利用这个特点可以进行传值。在iOS开发中,UIApplication就是个单例类,利用他可实现传值。
在UIApplication定义存储内容

//创建一个公共数组,用来存放数据,@property(nonatomic,retain) NSMutableArray * array;

在相应ViewController中使用

//应该去利用系统的UIApplication这个单例来获取系统已经创建好的那个AppDelegate里的对象//这是一个单例 对象,在整个程序中,只有一个唯一的实例存在UIApplication * application = [UIApplication sharedApplication];//通过这个单例对象来找到它持有的AppDelegate对象KGAppDelegate * appDelegate = application.delegate;//通过appDelegate对象拿到他的数组[appDelegate.array addObject:self.title];

3)使用自己的单例类进行传值
除了使用系统自带的单例类外,还可以使用自定义单例类用来传值
自定义单例类KGMyApplication
//为application类,添加一个属性,用来接收MyAppDelegate对象@property(nonatomic,retain) KGMyAppDelegate * delegate;
//使用这个方法来实例一个单例对象+(KGMyApplication *)sharedMyApplication;+(KGMyApplication *)sharedMyApplication{ static KGMyApplication * obj = nil; if (!obj) { //给obj创建单例对象 obj = [[KGMyApplication alloc]init]; 
//给单例对象的delegate属性赋值 obj.delegate = [[KGMyAppDelegate alloc]init]; } return obj;}

定义KGMyAppDelegate类保存数据

//这个类不是一个单例类,但是,需要在这里保存数据
@property(nonatomic,retain)NSMutableArray * array;

在相应ViewController中使用

//首先获取MyApplication的单例对象KGMyApplication * app = [KGMyApplication sharedMyApplication];//通过这个单例对象里的delegate属性来获取MyAppDelegate对象KGMyAppDelegate * appDelegate = app.delegate;//获取MyAppDelegate里的数组NSMutableArray * array = [appDelegate array];static int n = 0;[array addObject:[NSString stringWithFormat:@"VC1-%d",n++]];
4)使用通知中心NSNotificationCenter进行传值

通知由通知中心发送,通知中心在整个工程中只有一个。通知中心可以发送多条消息,可以在整个工程中的任何位置接收消息,通过通知中心的名称区分消息。
一个简单的应用,从界面2中发送通知,界面1中接收

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomeThing:) name:@"xiaoxi" object:nil];- (void)doSomeThing:(NSNotification *)noti{ NSLog(@"收到了"); label.text = [noti.userInfo objectForKey:@"key"];}

KGSecondViewController
    NSNotification *noti = [[NSNotification alloc]initWithName:@"xiaoxi" object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%@", btn.titleLabel.text],@"key", nil]];
 // 发送
    [[NSNotificationCenter defaultCenter] postNotification:noti];

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,875评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,569评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,475评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,459评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,537评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,563评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,580评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,326评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,773评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,086评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,252评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,921评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,566评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,190评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,435评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,129评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,125评论 2 352

推荐阅读更多精彩内容