参考:
http://blog.sina.com.cn/s/blog_4431c7610100vgds.html
http://blog.163.com/zhe8stianshi@126/blog/static/17176291920117233111605/
http://blog.csdn.net/riveram/article/details/7263322
一般方法
1)采用代理模式 子viewcontroller设计 代理协议,定义协议接口,父viewcontroller 实现协议接口,实现子viewcontroller 退出时将相关数据更新到父视图。
2)采用ios的消息机制 父viewcontroller注册消息 子viewcontroller 发送消息,触发父viewcontroller的消息处理。
3)采用database做为数据中间的存储媒介,子viewcontroller将状态数据存入DB,父viewcontroller从DB获取数据更新view。
4)采用ios的NSDefault 存储
5)通过AppDelegate 中定义全局变量实现中间数据的存储。
UIViewController和UIViewController之间的交互
1 单向交互。
- [[level2ViewController
alloc] init]; -
- [level2ViewController
setProp_1]; - [level2ViewController
setProp_2]; - [level2ViewController
setProp_3]; -
- [level1ViewController.
navigationController - pushViewController:level2ViewController];
-
- [level2ViewController
release];
2 双向交互,共享数据
- <span
style="font-size:16px;"></span><pre name="code" class="plain">[[shareData alloc] init]; - …
- [[level2ViewController
alloc] init]; -
- [level2ViewController
setProp_1]; - [level2ViewController
setProp_2]; - [level2ViewController
setData: shareData]; -
- [level1ViewController.
navigationController - pushViewController:level2ViewController];
-
- [level2ViewController
release];
就是使用MVC模式(UIViewController本身就是MVC中的C)。这个时候,shareData就不应该再是一个普通的数据,而应该封装成model,当model中的数据发生了改变的时候,会发出通知告诉C(和/或V)。这样的话,两个controller之间就比较松散了。引入dataModel后,伪代码如下:
- <span
style="font-size:16px;"></span><pre name="code" class="plain">[[shareData alloc] init]; - [dataModel
alloc] initWithData: shareData]; - …
- [[level2ViewController
alloc] init]; -
- [level2ViewController
setProp_1]; - [level2ViewController
setProp_2]; - [level2ViewController
setModel: dataModel]; -
- [level1ViewController.
navigationController - pushViewController:level2ViewController];
-
- [level2ViewController
release];
3 双向交互,逆向消息传递
4 双向交互,大量逆向消息传递
最后还要补充说明一些内容。
iphone 使用委托(delegate)在不同的窗口之间传递数据
在IOS里两个UIView窗口之间传递参数方法有很多,比如
1.使用SharedApplication,定义一个变量来传递.
2.使用文件,或者NSUserdefault来传递
3.通过一个单例的class来传递
4.通过Delegate来传递。
前面3种方法,暂且不说,这次主要学习如何使用通过Delegate的方法来在不同的UIView里传递数据 。
比如: 在窗口1中打开窗口2,然后在窗口2中填入一个数字,这个数字又回传给窗口1。
窗口1
窗口2
窗口2的结果传递给窗口1
1.首先定义个一委托UIViewPassValueDelegate用来传递值
- ( void )passValue:(NSString * )value;
@end
这个protocol 就是用来传递值
2.在窗口1的头文件里,声明delegate
#import " UIViewPassValueDelegate.h "
@interface DelegateSampleViewController : UIViewController < UIViewPassValueDelegate >
{
UITextField * _value;
}
@property(nonatomic, retain) IBOutlet UITextField * value;
- (IBAction)buttonClick:(id)sender;
@end
并实现这个委托
{
self.value.text = value;
NSLog( @" the get value is %@ " , value);
}
button的Click方法,打开窗口2,并将窗口2的delegate实现方法指向窗口1。
{
ValueInputView * valueView = [[ValueInputView alloc] initWithNibName: @" ValueInputView " bundle:[NSBundle mainBundle]];
valueView. delegate = self; // 把两个VC关联起来!
[self setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self presentModalViewController:valueView animated:YES];
}
第二个窗口的实现
.h 头文件
#import " UIViewPassValueDelegate.h "
@interface ValueInputView : UIViewController {
NSObject < UIViewPassValueDelegate > * delegate ;
UITextField * _value;
}
@property(nonatomic, retain)IBOutlet UITextField * value;
@property(nonatomic, retain) NSObject < UIViewPassValueDelegate > * delegate ;
- (IBAction)buttonClick:(id)sender;
@end
.m实现文件
@implementation ValueInputView
@synthesize delegate ;
@synthesize value = _value;
- ( void )dealloc {
[self.value release];
[super dealloc];
}
- (IBAction)buttonClick:(id)sender
{
[ delegate passValue:self.value.text]; // 具体的实现在第一个VC里。
NSLog( @" self.value.text is%@ " , self.value.text);
[self dismissModalViewControllerAnimated:YES];
}
- ( void )didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- ( void )viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code.
}
*/
@end
简单实现View直接的数据传递
废话就不说了,直接上步骤和代码:
1 创建一个基于Navigation-based Application的iphone工程,为什么要创建基于Navigation-based Application的工程呢,因为这样系统就会自动将Navigation视图加到我们的窗口视图中,这样我们就不用自己手动去加,并且可以用
[self.navigationControllerpushViewController:otherviewanimated:YES]去跳转页面。当设置每个页面的标题后会在页面左上角自动生成后退导航按钮,多方便呀,当然需要在建立后将xib文件里面的tableview去掉加入view。
2 新建一个页面,我这里是OtherView,让系统自动生成.h,.xib文件。
3 第一个页面上面添加一个文本筐和一个按钮,点击按钮后调转到第二个页面并将文本筐里面的数据传入第二个页面。第二个页面用一个label来显示传过来的数据。
4 代码:
首先是自动生成的协议里面的代码,注意看navigationController:
MynavAppDelegate.h代码:
- #import <UIKit/UIKit.h>
- @interface MynavAppDelegate : NSObject <UIApplicationDelegate> {
- }
- @property (nonatomic, retain) IBOutlet UIWindow *window;
- @property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
- @end
MynavAppDelegate.m代码:
- #import "MynavAppDelegate.h"
- @implementation MynavAppDelegate
- @synthesize window=_window;
- @synthesize navigationController=_navigationController;
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- self.window.rootViewController = self.navigationController;
- [self.window makeKeyAndVisible];
- return YES;
- }
- - (void)applicationWillResignActive:(UIApplication *)application
- {
- }
- - (void)applicationDidEnterBackground:(UIApplication *)application
- {
- }
- - (void)applicationWillEnterForeground:(UIApplication *)application
- {
- }
- - (void)applicationDidBecomeActive:(UIApplication *)application
- {
- }
- - (void)applicationWillTerminate:(UIApplication *)application
- {
- }
- - (void)dealloc
- {
- [_window release];
- [_navigationController release];
- [super dealloc];
- }
- @end
第一个页面的代码:
RootViewController.h
- #import <UIKit/UIKit.h>
- #import <Foundation/Foundation.h>
- @interface RootViewController : UIViewController {
- IBOutlet UITextField * message;//需要传出的数据
- }
- @property(nonatomic,retain) UITextField * message;
- -(IBAction) send;//按钮点击方法
- @end
RootViewController.m
- #import "RootViewController.h"
- #import "OtherView.h"
- @implementation RootViewController
- @synthesize message;
- -(IBAction) send{
- OtherView *otherview = [[OtherView alloc] initWithNibName:@"OtherView" bundle:nil];
- otherview.mystring= message.text;
- [self.navigationController pushViewController:otherview animated:YES];
- [otherview release];
- }
- - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
- UITouch *touch = [[event allTouches] anyObject];
- if (touch.tapCount >= 1) {
- [message resignFirstResponder];
- }
- }
- - (void)viewDidLoad
- {
- self.title = @"第一个页面";
- [super viewDidLoad];
- }
- - (void)didReceiveMemoryWarning
- {
- // Releases the view if it doesn't have a superview.
- [super didReceiveMemoryWarning];
- // Relinquish ownership any cached data, images, etc that aren't in use.
- }
- - (void)viewDidUnload
- {
- [super viewDidUnload];
- // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
- // For example: self.myOutlet = nil;
- }
- - (void)dealloc
- {
- [message release];
- [super dealloc];
- }
- @end
第二个页面代码:
OtherView.h
- #import <UIKit/UIKit.h>
- @interface OtherView : UIViewController {
- IBOutlet UILabel * mylabel;//用来显示传入的数据
- NSString * mystring;//数据传入用到的属性
- }
- @property(nonatomic,retain) UILabel * mylabel;
- @property(nonatomic,retain) NSString * mystring;
- @end
- #import "OtherView.h"
- @implementation OtherView
- @synthesize mylabel,mystring;
- - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
- {
- self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
- if (self) {
- // Custom initialization
- }
- return self;
- }
- - (void)dealloc
- {
- [mylabel release];
- [mystring release];
- [super dealloc];
- }
- - (void)didReceiveMemoryWarning
- {
- // Releases the view if it doesn't have a superview.
- [super didReceiveMemoryWarning];
- // Release any cached data, images, etc that aren't in use.
- }
- #pragma mark - View lifecycle
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- self.title = @"第二个页面";
- self.mylabel.text=mystring;
- // mylabel.text = mystring;
- // Do any additional setup after loading the view from its nib.
- }
- - (void)viewDidUnload
- {
- [super viewDidUnload];
- // Release any retained subviews of the main view.
- // e.g. self.myOutlet = nil;
- }
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- // Return YES for supported orientations
- return (interfaceOrientation == UIInterfaceOrientationPortrait);
- }
- @end