页面之间传值方式的总结,五种方式,通知,block,代理,单例,NSUERDEFALUT,
首先代码拿上
1:单例
2:通知
3:代理
4:block方法
5:NSUSERDEFAULT(沙盒文件)
先是单例类:
.h文件
@interface DataSource : NSObject @property (nonatomic, strong) NSString *myName;//单例的属性,用于传值 +(DataSource*)sharedDataSource;//建立单例对象 @end
.m文件
#import "DataSource.h" @implementation DataSource +(DataSource *)sharedDataSource{ static DataSource *dataSource = nil; static dispatch_once_t once; dispatch_once(&once, ^{ dataSource = [DataSource new]; }); return dataSource; }//返回一个静态的本类对象 @end
接下来是第一个接受传值的页面,使用xib方式创建:
先上.h文件:
#import <UIKit/UIKit.h> #import "SecondViewController.h" @interface RootViewController : UIViewController<secondViewDelegate> @end
在上.m文件
#import "RootViewController.h" #import "SecondViewController.h" #import "DataSource.h" @interface RootViewController () @property (weak, nonatomic) IBOutlet UILabel *nameLabel; @end @implementation RootViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // 传值方式2:通知:首先注册通知,使用选择器设置接收到通知,调用的方法 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ChangeNameNotification:) name:@"ChangeNameNotification" object:nil]; } - (IBAction)showSecondView:(id)sender { SecondViewController *second = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; second.delegate = self;//设置代理,传值方法3:代理 second.flag = 0; [self presentViewController:second animated:YES completion:nil]; } //4.显示的实现 -(void)showName:(NSString *)nameString{ self.nameLabel.text = nameString; } //传值方式2:通知:接受到通知,调用该方法显示通知 -(void)ChangeNameNotification:(NSNotification*)notification{ NSDictionary *nameDictionary = [notification userInfo]; self.nameLabel.text = [nameDictionary objectForKey:@"name"]; }
//传值方法4:block方法,点击对应按钮出发,设置好传值页面的block方法,进行跳转 - (IBAction)showSecondWithBlock:(id)sender { SecondViewController *second = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; second.flag = 1; [self presentViewController:second animated:YES completion:nil]; second.block = ^(NSString *str){ self.nameLabel.text = str;// 传值方法4:设置block方法为更改接收页面label的文本 }; } //传值方法2:通知,不使用时,删掉通知 -(void)dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self]; }
-(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; // 通过UserDefault方式取值 if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"myNameText"] length] != 0) { self.nameLabel.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"myNameText"]; [[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"myNameText"]; }//传值方法5:NSUSERDEFAULT,读取沙盒内的plist文件获取值
//传值方法1: 通过单例取值 DataSource *dataSource = [DataSource sharedDataSource]; if ([dataSource.myName length] != 0) { self.nameLabel.text = dataSource.myName; dataSource.myName = @""; }//直接设置或者获取单例对象,单例对象只有一个,所以能够用于传值; } @end
xib页面包括一个label用于显示,两个跳转按钮,一个正常跳转,另一个需要先设置block,再进行跳转
接下来是第二个传值页面
先是.h文件:
#import <UIKit/UIKit.h> //block传值1:定义一个block,参数为字符串 typedef void (^ablock)(NSString *str); //传值方法3:代理 声明协议及方法 @protocol secondViewDelegate -(void)showName:(NSString *)nameString; @end @interface SecondViewController : UIViewController @property (nonatomic, weak)id<secondViewDelegate> delegate;//传值方法2:代理.设置代理 @property (nonatomic, copy) ablock block;//传值方法4: 定义一个block属性 @property(nonatomic) NSInteger flag;//当前系统标示(0:其他传值方式;1:block传值方式) @end
再是.m文件:
#import "SecondViewController.h" #import "DataSource.h" @interface SecondViewController () @property (weak, nonatomic) IBOutlet UITextField *nameTextField; @property (weak, nonatomic) IBOutlet UIButton *delegateMethod; @property (weak, nonatomic) IBOutlet UIButton *notificationMethod; @property (weak, nonatomic) IBOutlet UIButton *blockMethod; @property (weak, nonatomic) IBOutlet UIButton *userDefaultMethod; @property (weak, nonatomic) IBOutlet UIButton *singletonMethod; @end @implementation SecondViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. } - (IBAction)Cancel:(id)sender { [self dismissViewControllerAnimated:YES completion:nil]; }
//传值方式3:调用代理,直接调用代理,跳转接受页面 - (IBAction)delegateMethod:(id)sender { if ([self notEmpty]) { [self.delegate showName:self.nameTextField.text]; [self dismissViewControllerAnimated:YES completion:nil]; }else{ [self showAlert]; } } -(IBAction)backDown:(id)sender{ [self.nameTextField resignFirstResponder]; } //传值方式2:通知.创建一个通知对象及发送通知 - (IBAction)notificationMethod:(id)sender { if ([self notEmpty]) { [[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeNameNotification" object:self userInfo:@{@"name":self.nameTextField.text}]; [self dismissViewControllerAnimated:YES completion:nil]; }else{ [self showAlert]; } } //传值方式4:block传值2:在传值页面中,当输入名字,点击对应的确定按钮后,直接调用本身的block方法,由于跳转之前已经设置为更改接受页面的label,传值成功 - (IBAction)blockMethod:(id)sender { if ([self notEmpty]) { if (self.block) { self.block(self.nameTextField.text); [self dismissViewControllerAnimated:YES completion:nil]; } }else{ [self showAlert]; } } //用于检测是否输入框为空 -(BOOL)notEmpty{ if ([self.nameTextField.text length] == 0) { return NO; } return YES; } -(void)showAlert{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"请输入名字" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil]; [alert show]; }
//传值方式5:NSUSERDEFAULT 通过文件或者UserDefault方式存值 - (IBAction)userDefaultMethod:(id)sender { if ([self notEmpty]) { [[NSUserDefaults standardUserDefaults] setObject:self.nameTextField.text forKey:@"myNameText"];//使用kvc方法设置 [self dismissViewControllerAnimated:YES completion:nil]; }else{ [self showAlert]; } } //传值方式1:单例 写入要传入的数据(单例对象只有一个,所以能够进行传值) - (IBAction)singletonMethod:(id)sender { if ([self notEmpty]) { DataSource *dataSource = [DataSource sharedDataSource]; dataSource.myName = self.nameTextField.text; [self dismissViewControllerAnimated:YES completion:nil]; }else{ [self showAlert]; } }
-(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; if (self.flag == 0) { self.delegateMethod.hidden = NO; self.notificationMethod.hidden = NO; self.blockMethod.hidden = YES; self.userDefaultMethod.hidden = NO; self.singletonMethod.hidden = NO; }else{ self.delegateMethod.hidden = YES; self.notificationMethod.hidden = YES; self.blockMethod.hidden = NO; self.userDefaultMethod.hidden = YES; self.singletonMethod.hidden = YES; } }//根据flag来决定哪些按钮不显示 @end
传值页面的xib依据接受页面的跳转
使用block就只显示block按钮,点击返回
使用正常按钮,就会显示另外其他四种方法.
总结五种传值方法:
1:单例 需要创建单例类,适用于某些特殊场合(例如用户的信息); 使用单例内的方法,可以获得唯一对象(即单例对象),即可以实现传值
//2015-9-23(使用UIApplication 单例,系统级对象传值----随笔《关于UIApplication单例传值》)
2:通知 传值方可以直接创建通知,并发送通知, 而接受方则需要先注册,同时声明接受通知后调用的方法(注意,方法传值是传递NSNotification对象,使用userinfo获取内部的字典)
3:代理 代理方需要在委托类内声明一个协议,还需要一个使用该协议的属性, 在委托方则需要先使用协议,并且实现协议内的方法, (由于协议内的方法可以传值给委托方的属性,从而实现传值)!!!!!------注意 在跳转之前,需要在委托方内设置代理方内的代理为本身(委托方)
4:block方法 与代理传值相近, 在传值页面,需要声明一个block属性(该属性内是方法), 在接受方跳转前实现block方法,方法具体实现在接受方,从而达到传值的目的. 跳转完成后,在传值方内调用block属性方法(该属性内是方法),即可实现传值
5:NSUSERDEFAULT(沙盒文件) 存储在沙盒文件内,安全性相对较高,常用于存储用户的偏好设置与用户的登录信息 先使用系统方法获取,再使用kvc的方式设置值,在接受方内使用系统方法获取,使用字典方式获取即可;