iOS几种常见的页面传值方式

Posted APP技术社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS几种常见的页面传值方式相关的知识,希望对你有一定的参考价值。

几种常见的页面传值方式:

  1. 属性传值

最简单的传值方式,正向传递。

  1. 单例传值

很灵活,可以双向传递。(写入内存读取)

  1. NSUserDefaults传值

可以双向传递。(写入沙盒文件读取)

利用 NSUserDefaults类 将数据存储起来,在第二个页面中读取。

  1. 代理传值(最经典)

多用于反向传递

在第二个页面中定义一个协议,并调用。让第一个页面也遵守这个协议,并实现传递数据的方法。

  1. block传值(官方推荐 最流行)

多用于反向传递

在第二个页面中定义一个block,并调用。并且在第一个页面中实现。

  1. 通知传值

多用于反向传值。

第一个页面监听 消息中心,第二个页面发送消息给消息中心。


1、属性传值

在第二个页面 中定义一个属性,在第一个页面中赋值。并在第二个页面中取出来使用。


考虑采用UINavigationController方式作为页面跳转机制

指定AppDelegate.h根控制器并显示


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];  //创建导航控制器 UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController: [[ViewController alloc]init]];  //设置window的根控制器 self.window.rootViewController = nav;  //设置并显示 [self.window makeKeyAndVisible]; return YES; }


实现A与B界面传值,需要新建两个UIViewController

A --> AUIViewController

b --> BUIViewController

AUIViewController.h


#import <UIKit/UIKit.h> @interface AUIViewController : UIViewController @end


BUIViewController.h

为实现A-->B 属性传值,需要在B中添加属性。然后在跳转前给B中的属性赋值,在B中获取自己的属性值就OK了。


#import <UIKit/UIKit.h> @interface BUIViewController : UIViewController//传递值属性@property(nonatomic,strong) NSString * bValue;@end

详细代码如下:
#import "AUIViewController.h"#import "BUIViewController.h"#import "MyInstance.h"@interface AUIViewController ()//准备在界面创建两个控件,一个输入文字,一个用来跳转@property (strong,nonatomic) UIButton *button;@property (strong,nonatomic) UITextField *textField;@end @implementation AUIViewController- (void)viewDidLoad{ [super viewDidLoad]; self.navigationItem.title = @"A界面"; //将控件添加到View上 [self.view addSubview:self.button]; [self.view addSubview:self.textField];}- (UIButton *)button{ if(!_button){ _button = [UIButton alloc]initWithFrame:CGRectMake(100,100,200,100); [_button setTitle:@"go to B View" forState:UIControlStateNormal]; [_button addTarget:self action:@selector(btnOnClick) forControlEvents:UIControlEventTouchUpInside]; }}- (UITextField *)textField{ if(!_textField){ _textField = [UITextField alloc]initWithFrame:CGRectMake(100,200,200,40); [_textField setFont:[UIFont systemFontSize:18]]; }}//点击事件-(void)btOnClick{ BUIViewController *BVC = [[BUIViewController alloc]init]; //属性传值给B NSString *textfieldStr = self.textField.text; //BVC.BValue = @"属性传值:A --> B"; BVC.bValue = textfieldStr; [self.navigationController pushViewController:BVC animated:YES];}@end
#import "BUIViewController.h"#import "MyInstance.h"@interface BUIViewController ()//准备在界面创建两个控件,一个输入文字,一个用来跳转@property (strong,nonatomic) UIButton *button;@property (strong,nonatomic) UITextField *textField;@end @implementation BUIViewController- (void)viewDidLoad{ [super viewDidLoad]; self.navigationItem.title = @"B界面"; //将控件添加到View上 [self.view addSubview:self.button]; [self.view addSubview:self.textField]; //打印上一个界面传递过来的值 _textField.text = self.bValue; NSLog(@"%@--%@",[self class],self.bValue);}- (UIButton *)button{ if(!_button){ _button = [UIButton alloc]initWithFrame:CGRectMake(100,100,200,100); [_button setTitle:@"返回" forState:UIControlStateNormal]; [_button addTarget:self action:@selector(backClick) forControlEvents:UIControlEventTouchUpInside]; }}- (UITextField *)textField{ if(!_textField){ _textField = [UITextField alloc]initWithFrame:CGRectMake(100,200,200,40); [_textField setFont:[UIFont systemFontSize:18]]; }}//点击事件(返回上一个界面)-(void)backClick{ [self.navigationController popViewControllerAnimated:YES];}@end


2、单例传值

需要定义一个静态单例,第一个页面赋值给静态对象,第二个页面从其中取值。

MyInstance.h

#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface MyInstance : NSObject@property(nonatomic, strong) NSString *str;+(instancetype) sharedInstance;@endNS_ASSUME_NONNULL_END

MyInstance.m#import "MyInstance.h"@implementation MyInstance//单例对象+ (instancetype) sharedInstance { static DefaultInstance *sharedVC = nil; if(sharedVC == nil) { sharedVC = [[MyInstance alloc] init]; } return sharedVC;}@end

第一个页面给单例赋值


 
SecondviewController *secondViewController = [[SecondviewController alloc] init]; //属性传值//secondViewController.str = @"属性传递的值"; //传递[MyInstance sharedInstance].str = @"单例传值"; // 从页面一 给单例对象赋值[self presentViewController:secondViewController animated:YES completion:nil];

第二个页面取出相应的值


@implementation SecondviewController- (UITextField *)textField { if(!_textField) { _textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 200, 40)]; _textField.textColor = [UIColor blackColor]; _textField.backgroundColor = [UIColor whiteColor]; _textField.borderStyle = UITextBorderStyleLine;  //单例传值 -- 接收 显示 _textField.text = [MyInstance sharedInstance].str; }  return _textField;}


3、NSUserDefaults传值

利用 NSUserDefaults类 将数据存储起来,在第二个页面中读取。

NSUserDefaluts根单例类似,只不过NSUserDefaluts是将数据写入到文件中(沙盒文件)


如上图,我们可以看出沙盒文件传流程。同样我们在A跟B之间的传值,方式如上图,在A跳转到B的时候将数据写入文件中,在B中读取。


关键代码 A跳转B前写入数据:


//获取单例对象NSUserDefaults * ud = [NSUserDefaults standardUserDefaults];//设置存储的数据[ud setObject:@"value" forKey:@"key"];//立即写入[ud synchronize];

读取数据:
//获取单例对象NSUserDefaults * ud = [NSUserDefaults standardUserDefaults];//打印读取数据NSLog(@"%@",[ud objectForKey:@"key"]);

4、代理传值

在第二个页面中定义一个协议,并调用。让第一个页面也遵守这个协议,并实现传递数据的方法。


//委托方创建一个协议@protocol passValueDelegate <NSObject>// 定义一个传值的方法- (void)passValue: (NSString *) str;@end

//委托方调用并传值//代理传值 -- 反向[self.delegate passValue:self.textField.text];

//接收者需要遵守这个协议@interface ViewController () <passValueDelegate>@property(nonatomic, strong)UILabel *label;@property(nonatomic,strong) UIButton *btn;@end......//代理传值实现协议方法,接收来自委托方的值- (void)passValue:(NSString *)str{ self.label.text = str;}

5、block传值

在第二个页面中定义一个block,并调用。并且在第一个页面中实现。


//定义一个block进行页面反向传值@property(nonatomic,strong) void(^Myblcok) (NSString *);

//第二个页面调用定义的block,并传值self.Myblcok(_textField.text);
//btn点击事件,跳转到页面2- (void)btnClick{ BUIViewController *bUIViewController = [[BUIViewController alloc] init]; //第一个页面实现这个block,接收来自页面二的值 bUIViewController.Myblcok = ^(NSString *str){ self.label.text = str; }; [self presentViewController:bUIViewController animated:YES completion:nil];}

6、通知传值

第一个页面监听 消息中心,第二个页面发送消息给消息中心。


 
// 添加监听,等待页面B的传值[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notHandle:) name:@"notify" object:nil];......//接收到通知之后的处理- (void) notHandle: (NSNotification *) not{ self.label.text = not.userInfo[@"not"];}

//通知传值 --- 发送通知[[NSNotificationCenter defaultCenter] postNotificationName:@"notify" object: nil userInfo: @{@"not": self.textField.text}];//返回上一个页面[self dismissViewControllerAnimated:YES completion:nil];

以上是关于iOS几种常见的页面传值方式的主要内容,如果未能解决你的问题,请参考以下文章

iOS 页面间几种传值方式(属性,代理,block,单例,通知)

iOS 页面间几种传值方式(属性,代理,block,单例,通知)

iOS 页面间几种传值方式(属性,代理,block,单例,通知)

iOS 页面间几种传值方式(属性,代理,block,单例,通知)(转)

iOS学习之六种传值方式

jsp 页面间传值有几种方式?分别是哪几种?