iOS开发中视图控制器ViewControllers之间的数据传递
iOS开发中视图控制器ViewControllers之间的数据传递
这里我们用一个demo来说明ios是如何在视图控制器之间传递重要的参数的。本文先从手写UI来讨论,在下一篇文章中讨论在storyboard中传递数据。
首先新建一个空工程,并添加一个根视图控制器类,如下图所示:
#
在函数didFinishLunchingWithOption中添加几行代码,完成后如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; RootViewController *myRootViewController = [[RootViewController alloc] init]; myRootViewController.view.backgroundColor = [UIColor lightGrayColor]; self.window.rootViewController = myRootViewController; return YES;} |
完成以后运行,iOS模拟器显示结果如下:
#
由图中可以看出,我们自定义的myRootViewController已经成功在启动时加载,显示出了一个浅灰色的界面。
随后如法炮制新建另一个viewController命名为FirstSubViewController,同时在RootViewController的viewDidLoad函数中添加如下代码:
|
1
2
3
4
5
6
7
8
9
10
|
- (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view. UIButton *firstVC = [UIButton buttonWithType:UIButtonTypeSystem]; firstVC.frame = CGRectMake(60, 244, 200, 80); [firstVC setTitle:@"显示下一个视图" forState:UIControlStateNormal]; [firstVC addTarget:self action:@selector(displayNextViewController) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:firstVC];} |
之后还需定义一个函数,名为displayNextViewController,函数体暂时设为空。此时运行程序,界面中央将显示一个按钮“显示下一个视图”,但是单击该按钮没有任何反应。这是因为响应函数displayNextViewController还没有实现。现在在该函数中添加代码:
|
1
2
3
4
5
6
7
|
- (void)displayNextViewController{ FirstSubViewController *firstSubVC = [[FirstSubViewController alloc] init]; [self presentViewController:firstSubVC animated:YES completion:^{ NSLog(@"present first sub VC ok"); }];} |
完成后运行程序发现,按钮已经有反应了,按下后回出现一个新的白色背景的新界面,这就是我们在这里定义的firstSubVC;
下一步实现界面的返回操作。在FirstSubViewController的viewDidLoad函数中建立一个回退按钮,并实现其响应函数。代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
- (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view. UIButton *goBack = [UIButton buttonWithType:UIButtonTypeSystem]; goBack.frame = CGRectMake(60, 244, 200, 80); [goBack setTitle:@"返回上级界面" forState:UIControlStateNormal]; [goBack addTarget:self action:@selector(goBackToPreviousViewController) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:goBack];}- (void)goBackToPreviousViewController{ [self dismissViewControllerAnimated:YES completion:^{ NSLog(@"Back to previous OK"); }];} |
到此为止,我们已经通过presentViewController和dismissViewController实现了视图的切换,下面来考虑两个视图控制器之间的数据交流的问题。
在此之前,分别在RootViewController和FirstSubViewController中添加一个标签和文本框,作为数据的显示和输入部分。我们的目的是在FirstSubViewController中输入一个数字,然后再RootViewController显示出来。
在这两个类中分别用property来实现文本框和标签栏:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
//RootViewController.m@interface RootViewController ()@property (strong,nonatomic) UILabel *lable;@end@implementation RootViewController- (UILabel *)lable{ if (!_lable) { _lable= [[UILabel alloc] initWithFrame:CGRectMake(60, 150, 200, 30)]; _lable.textAlignment = NSTextAlignmentCenter; _lable.text = @"Hello World!"; _lable.backgroundColor = [UIColor whiteColor]; } return _lable;}…..@end//FirstSubViewController@interface FirstSubViewController ()@property (strong,nonatomic) UITextField *inputText;@end@implementation FirstSubViewController- (UITextField *)inputText{ if (!_inputText) { _inputText = [[UITextField alloc] initWithFrame:CGRectMake(60, 150, 200, 30)]; _inputText.backgroundColor = [UIColor lightGrayColor]; } return _inputText;}…..@end |
在这两个视图控制器的viewDidLoad中分别添加如下代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//RootViewController.m- (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view. [self.view addSubview:self.label]; UIButton *firstVC = [UIButton buttonWithType:UIButtonTypeSystem]; …..}…..//FirstSubViewController- (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view. //添加输入框 [self.view addSubview:self.inputText]; UIButton *goBack = [UIButton buttonWithType:UIButtonTypeSystem]; …..} |
在视图控制器之间进行数据传递可以通过多种方法,下面将逐个实验:
1、使用代理delegate的方法:
基本原理:FirstSubViewControllers试图改变RootViewController的数据,但是除了操作自己内部的数据的能力之外,不能改变其他类的数据。想要将这些数据传递出去,需要设置代理方法,获取FirstSubViewControllers中数据的类来遵循该方法,通过实现该代理协议中的方法来获取FirstSubViewControllers中的数据。
具体步骤:
首先在FirstSubViewController.h中定义协议:
|
1
2
3
4
5
6
|
@protocol FirstSubViewControllerDelegate <nsobject>@optional- (void)getStringFromFirstSubViewControllerDelegate:(NSString *)outputString;@end</nsobject> |
然后添加一个符合该协议的代理属性:
|
1
2
|
@property (nonatomic,weak) id<firstsubviewcontrollerdelegate> delegate;</firstsubviewcontrollerdelegate> |
在RootViewControlller.h中,声明该类符合FirstSubViewControllerDelegate协议:
|
1
|
@interface RootViewController : UIViewController<firstsubviewcontrollerdelegate></firstsubviewcontrollerdelegate> |
在新建FirstSubViewController的实例后,将其delegate属性定义为self,同时实现协议中的方法,两个函数如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
- (void)getStringFromFirstSubViewControllerDelegate:(NSString *)outputString{ self.lable.text = outputString;}- (void)displayNextViewController{ FirstSubViewController *firstSubVC = [[FirstSubViewController alloc] init]; firstSubVC.delegate = self; [self presentViewController:firstSubVC animated:YES completion:^{ NSLog(@"present first sub VC ok"); }];} |
最后在FirstSubViewController.m的goBackToPreviousViewController中添加一句向delegate属性发送获取数据的消息:
|
1
2
3
4
5
6
7
|
- (void)goBackToPreviousViewController{ [self.delegate getStringFromFirstSubViewControllerDelegate:self.inputText.text]; [self dismissViewControllerAnimated:YES completion:^{ NSLog(@"Back to previous OK"); }];} |
这样,大功告成了,在FirstSubViewController中的输入框中输入的内容,在按返回按钮后回显示在第一个界面的标签上。
2、使用通知Notification的方法
关于通知的知识在未来将会详述,在这里只是简要介绍一种使用通知这一机制的方法。
在使用通知之前,必须在默认通知中心里添加一个所谓“观察者”和通知,这个通知是命名的,同时还指定了回调的方法。当该通知中心收到了某个对象发送了相应的通知时,将会调用指定的方法执行某项操作。通知的发送者同时还可以发送相应的消息作为通知的参数。
注册通知中心可以在RootViewController.m中的viewDidLoad函数的末尾添加如下函数:
|
1
2
|
//使用通知的方式实现[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeLabelText:) name:@"ChangeLabelTextNotification" object:Nil]; |
此外还要实现观察者的回调函数:
|
1
2
3
4
5
|
- (void)changeLabelText:(NSNotification *)notification{ id text = notification.object; _lable.text = text;} |
自此通知的接收端已经完成。
通知的发送端,只需在“返回上级界面”的相应函数中按照事先定义的名称发送通知和参数即可:
|
1
2
|
//使用通知方式实现[[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeLabelTextNotification" object:_inputText.text]; |
此时运行,将会发现和代理模式起到了相同的作用。
除了代理和通知之外,还有其他如KVO等方法,未来还会详细探讨。
iOS开发中视图控制器ViewControllers之间的数据传递的更多相关文章
- iOS开发中视图相关的小笔记:push、modal、popover、replace、custom
在storyboard中,segue有几种不同的类型,在iphone和ipad的开发中,segue的类型是不同的. 在iphone中,segue有:push,modal,和custom三种不同的类型, ...
- ASP.NET MVC3中Controller与View之间的数据传递
在ASP.NET MVC中,经常会在Controller与View之间传递数据,因此,熟练.灵活的掌握这两层之间的数据传递方法就非常重要.本文从两个方面进行探讨: 一. Controller向Vie ...
- iOS开发之视图控制器(UIViewController)
视图控制器应该在MVC设计模式中扮演控制层(C)的角色,UIViewController的职责对内管理与之关联的View,对外跟其他UIViewController通信和协调.一个视图控制器管理一个视 ...
- ASP.NET MVC3中Controller与View之间的数据传递总结
一. Controller向View传递数据 1. 使用ViewData传递数据 我们在Controller中定义如下: ViewData["Message_ViewData& ...
- Asp.net MVC中 Controller 与 View之间的数据传递
在ASP.NET MVC中,经常会在Controller与View之间传递数据 1.Controller向View中传递数据 (1)使用ViewData["user"] (2)使用 ...
- MVC中Controller与View之间的数据传递
一.Controller向View传递数据 Controller向View传递数据有3种形式: 通过ViewData传递 在Controller里面的Action方法中定义ViewData,并且赋值, ...
- iOS开发系列--视图切换
概述 在iOS开发中视图的切换是很频繁的,独立的视图应用在实际开发过程中并不常见,除非你的应用足够简单.在iOS开发中常用的视图切换有三种,今天我们将一一介绍: UITabBarController ...
- 怎样实现IOS开发中的数据存储方式
iOS 开发中,一般有如下几种数据存储方式.需要根据具体的业务场景,选择 合适的数据存储方式. (1) 用户默认设置 – 这种情况通常不需要用户干预,如游戏通关信息,Video 播放记录,或者 Ap ...
- IOS开发中UITableView(表视图)的滚动优化及自定义Cell
IOS开发中UITableView(表视图)的滚动优化及自定义Cell IOS 开发中UITableView是非常常用的一个控件,我们平时在手机上看到的联系人列表,微信好友列表等都是通过UITable ...
随机推荐
- HDU 4738 Caocao's Bridges(割边)
乍一看一个模板题,仔细一看还是模板题,但是三个坑.1,不是连通图,放0个.2 守卫为0,放1个. 3注意重边. #include<iostream> #include<cstdio& ...
- MVC工作流程
1 浏览者 => 调用控制器,对它发出指令 2 控制器 => 按照指令选取一个合适的模型 3 模型 => 按控制器指令取出相应的数据 4 控制器 => 按指令选取 ...
- R语言——基本绘图函数
通过一个综合的例子测试绘图函数 学习的内容是tigerfish老师的教程. 第一节:基本知识 用seq函数产生100位学生的学号. > num = seq(,) > num [] [] [ ...
- IIS Express允许外部访问(外部调试)
Visual Studio配合IIS Express为Web开发提供了强劲的调试功能,本文介绍IIS Express如何在调试模式下让局域网的其他设备进行访问,以便进行测试. 1.打开IIS Expr ...
- Windows API 之 CreateThread、WaitForSingleObject(未完)
WaitForSingleObject Waits until the specified object is in the signaled state or the time-out interv ...
- Android Stduio的使用(七)--Structure窗口
1.本篇博文介绍Android查看.Java文件中所有属性和类方法的工具:Structure窗口 2.我们知道Eclipse的OutLine窗口可以查看.java文件所有的属性和方法. 2.Andro ...
- 【转载】linux环境下为firefox/chrome浏览器安装flash player
本文转载自 http://blog.sina.com.cn/s/blog_6ad624380102v1xf.html firefox安装flash player的方法: 先到adobe网站上下 ...
- 求余区间的求和类问题 离线+线段树 HDU4228
题目大意:给一个数组a,他的顺序是严格的单调增,然后有如下三个操作 ①加入一个val到a数组里面去,加入的位置就是a[i-1]<val<a[i+1] ②删除一个a[i]=val的值 ③查询 ...
- UVA699 dfs and map
和书上的方法不一样... 因为我不知道节点,所以就直接用map来存左右了. #include<bits/stdc++.h> using namespace std; map <int ...
- SD卡读写扇区注意事项(转)
源:http://blog.163.com/zhaojun_xf/blog/static/30050580201151410635516/ 在调试SD卡时,大家都喜欢使用扇区进行验证.也就是说,一般都 ...