iOS五种页面传值方式
来源:互联网 发布:php空间试用 编辑:程序博客网 时间:2024/06/10 18:46
页面传值是很常用的一个东西,这里介绍比较常用的五种:属性传值,block传值,代理传值,单例传值,通知传值。
(一)属性传值
实践方案:第二个界面中的lable显示第一个界面textField中输入的文本
实践步骤:
首先我们建立一个RootViewControllers和一个DetailViewControllers(detail页面的label显示root页面textField输入的内容),在DetailViewControllers中声明一个textString属性,用于接收传过来的字符串:
//DetailViewControllerOne.h#import <UIKit/UIKit.h>@interface DetailViewControllerOne : UIViewController@property (nonatomic , strong) NSString *textString;@end
同时创建一个Lable用来显示传过的字符串
//DetailViewControllerOne.m#import "DetailViewControllerOne.h"@interface DetailViewControllerOne ()@end@implementation DetailViewControllerOne- (void)viewDidLoad { [super viewDidLoad]; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds)-40, 30)]; label.backgroundColor = [UIColor orangeColor]; label.font = [UIFont systemFontOfSize:20]; label.numberOfLines = 0; label.text = self.textString; //使用传递过来的值 [self.view addSubview:label]; self.view.backgroundColor = [UIColor greenColor];}
在RootViewControllers上引入DetailViewControllers同时声明一个textField属性用来输入字符串
//RootViewControllers.m#import "RootViewControllerOne.h"#import "DetailViewControllerOne.h"@interface RootViewControllerOne ()@property(nonatomic , strong) UITextField *textField;@end@implementation RootViewControllerOne- (void)viewDidLoad { [super viewDidLoad]; self.title = @"属性传值"; self.view.backgroundColor = [UIColor whiteColor]; [self.view addSubview:self.textField]; // 创建一个轻拍手势,当点击屏幕任何一个地方,就取消键盘的第一响应,隐藏键盘 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; [self.view addGestureRecognizer:tap]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(20, 200, CGRectGetWidth(self.view.bounds)-40, 40); [button setTitle:@"下一页" forState:UIControlStateNormal]; button.titleLabel.font = [UIFont systemFontOfSize:20]; button.backgroundColor = [UIColor greenColor]; [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button];}-(UITextField *)textField { if (!_textField) { _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds)-40, 40)]; _textField.backgroundColor = [UIColor greenColor]; _textField.placeholder = @"请输入内容"; } return _textField;}//放弃作为第一响应者- (void)handleTap:(id)sender { [_textField resignFirstResponder];}//页面跳转-(void)clickAction:(id)sender { DetailViewControllerOne *dVC = [[DetailViewControllerOne alloc] init]; dVC.textString = self.textField.text; //利用detail的textString属性保存textField输入的内容 [self.navigationController pushViewController:dVC animated:NO];}
小结:属性传值的核心就是在一个页面通过使用另一个页面的属性,利用这个属性来保存需要传递的信息,从而达到在另一个页面能使用前一个页面传递过来的信息。
(二)Block传值
实践方案:当第二个页面返回第一个页面时,在第一个页面中的lable显示第二个界面textField中输入的文本
实践步骤:
首先我们建立一个RootViewControllers和一个DetailViewControllers(root页面的label显示detail页面textField输入的内容),在RootViewControllers里面新建一个用于显示的Label
//RootViewControllers.h#import <UIKit/UIKit.h>@interface RootViewControllerTwo : UIViewController@property (nonatomic,retain) UILabel *label;@end
在DetailViewControllers里面新建一个用于传值的Block,一个Block方法和一个用于输入内容的textField
//DetailViewControllers.h#import <UIKit/UIKit.h>typedef void (^ReturnTextBlock)(NSString *showText);//重新定义了一个名字@interface DetailViewControllerTwo :UIViewController@property (nonatomic,retain) UITextField *tf;@property (nonatomic,copy) ReturnTextBlock returnTextBlock;//定义的一个Block属性- (void)returnText:(ReturnTextBlock)block;@end
将传递过来的block赋值给自己的属性block,然后找一个时机给block传递数据
//DetailViewControllers.m#import "DetailViewControllerTwo.h"#import "RootViewControllerTwo.h"@implementation DetailViewControllerTwo- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; //定义一个输入框 将文字传给第一个界面,并且显示在前一个页面的UILabel上 self.tf = [[UITextField alloc]initWithFrame:CGRectMake(20,100,CGRectGetWidth(self.view.bounds) - 40 , 40)]; self.tf.tintColor = [UIColor orangeColor]; self.tf.backgroundColor = [UIColor greenColor]; self.tf.placeholder = @"请输入内容"; [self.view addSubview:self.tf]; //定义一个按钮 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(20,300,CGRectGetWidth(self.view.bounds) - 40 , 40); button.backgroundColor = [UIColor redColor]; [button setTitle:@"返回" forState:UIControlStateNormal]; [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button];}/*在第一个界面传进来一个Block语句块的函数,把传进来的Block语句块保存到本类的实例变 量returnTextBlock(.h中定义的属性)中,然后寻找一个时机调用*/-(void)returnText:(ReturnTextBlock)block{ self.returnTextBlock = block;}//而这个时机就是当视图将要消失的时候,需要重写:-(void)viewWillDisappear:(BOOL)animated{ if (self.returnTextBlock !=nil) { self.returnTextBlock(self.tf.text); }}//此处的点击事件也会触发视图消失,所以同样会走上面的viewWillDisappear方法-(void)clickAction:(id)sender { [self.navigationController popViewControllerAnimated:NO];}@end
读取block传递过来的数据,并显示在label中
//RootViewControllers.m#import "RootViewControllerTwo.h"#import "DetailViewControllerTwo.h"@interface RootViewControllerTwo ()@end@implementation RootViewControllerTwo- (void)viewDidLoad { [super viewDidLoad]; self.title = @"Block传值"; self.view.backgroundColor = [UIColor whiteColor]; //定义一个按钮 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(20,300,CGRectGetWidth(self.view.bounds) - 40 , 40); button.backgroundColor = [UIColor blueColor]; [button setTitle:@"下一页" forState:UIControlStateNormal]; [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; //定义一个显示控件 self.label = [[UILabel alloc] initWithFrame:CGRectMake(20,100, CGRectGetWidth(self.view.bounds) - 40 , 40)]; self.label.backgroundColor = [UIColor purpleColor]; self.label.text = @"用于显示从后面页面返回的数据";//为了显示第二个视图控制器传过来的字符串 self.label.textColor = [UIColor whiteColor]; [self.view addSubview:self.label];}-(void)clickAction:(id)sender{ DetailViewControllerTwo * dVC =[[DetailViewControllerTwo alloc] init];//相对应的将其实例化,否则找不到相应的属性 //回调方法将输入框中的数据传输过来 [dVC returnText:^(NSString *showText) { self.label.text = showText; }]; [self.navigationController pushViewController:dVC animated:YES];}
小结:其实block传值还是有点类似于属性传值,但是他是将值保存在代码块中,通过关联传递过来的代码块(页面一)与自己的属性代码块(页面二),以及使用代码块传值(页面二),回到页面一中,页面一回调代码块,以获取代码块传递过来的值。
(三)代理传值
实践方案:第一个界面中的lable显示第二个界面textField中输入的文本
实践步骤:
首先我们建立一个RootViewControllers和一个DetailViewControllers(root页面的label显示detail页面textField输入的内容),首先我们先声明一个代理以及代理需要实现的方法
//DetailViewController.h#import <UIKit/UIKit.h>@class DetailViewControllerThree;@protocol PassingValueDeletegate <NSObject>@optional-(void)viewController:(DetailViewControllerThree *)viewController didPassingValueWithInfo:(id)info;@end@interface DetailViewControllerThree : UIViewController@property(nonatomic, assign) id<PassingValueDeletegate> delegate;//通过代理传值@end
在一个需要传值的时机,将需要传递的值保存到代理方法的参数中
//DetailViewController.m#import "DetailViewControllerThree.h"@interface DetailViewControllerThree ()@property (nonatomic, strong) UITextField *textField;@end@implementation DetailViewControllerThree- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor whiteColor]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds)-40, 40); [button setTitle:@"返回" forState:UIControlStateNormal]; button.backgroundColor = [UIColor blueColor]; [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; [self.view addSubview:self.textField];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; NSString *string; if ([_textField.text length] == 0) { string = @"用户未输入任何内容"; }else { string = _textField.text; } //视图将要消失,通过代理传值 //首次判断代理是否存在,并在代理能够响应代理方法时才执行代理方法 if (self.delegate && [self.delegate respondsToSelector:@selector(viewController:didPassingValueWithInfo:)]) { [self.delegate viewController:self didPassingValueWithInfo:string]; }}-(UITextField *)textField { if (!_textField) { _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) - 40, 40)]; } _textField.placeholder = @"请输入内容"; _textField.backgroundColor = [UIColor greenColor]; return _textField;}-(void)clickAction:(id)sender { [self.navigationController popViewControllerAnimated:NO];}
声明RootViewController实现该代理,并实现该代理的方法,而该代理方法就包含着传递过来的值
//RootViewController.m#import "RootViewControllerThree.h"#import "DetailViewControllerThree.h"@interface RootViewControllerThree () <PassingValueDeletegate>@property (nonatomic, strong) UILabel *showLabel;@end@implementation RootViewControllerThree- (void)viewDidLoad { [super viewDidLoad]; self.title = @"代理传值"; self.view.backgroundColor = [UIColor whiteColor]; [self.view addSubview:self.showLabel]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds)-40, 40); [button setTitle:@"下一页" forState:UIControlStateNormal]; button.titleLabel.font = [UIFont systemFontOfSize:20]; button.backgroundColor = [UIColor greenColor]; [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}- (UILabel *)showLabel { if (!_showLabel) { _showLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 200, CGRectGetWidth(self.view.bounds)-40, 40)]; } _showLabel.text = @"用于显示后面页面传过来的值"; _showLabel.textColor = [UIColor whiteColor]; _showLabel.backgroundColor = [UIColor purpleColor]; return _showLabel;}-(void)clickAction:(id)sender { DetailViewControllerThree *dVC = [[DetailViewControllerThree alloc] init]; dVC.delegate = self; [self.navigationController pushViewController:dVC animated:NO];}-(void)viewController:(DetailViewControllerThree *)viewController didPassingValueWithInfo:(id)info { _showLabel.text = info; //代理方法传递过来的值}
小结:代理方法是用的比较多的,适用于任意界面之间传值,只需要声明实现代理方法,就可以获取传递过来的值
(四)单例传值
实践方案:第一个界面中的lable显示第二个界面textField中输入的文本,同时第二个界面中的lable显示第一个界面textField中输入的文本,输入文本互相传递
实践步骤:新建一个单例
#import <Foundation/Foundation.h>@interface AppStatus : NSObject { NSString *_contextStr;}@property(nonatomic,retain)NSString *contextStr;+(AppStatus *)shareInstance;@end#import "AppStatus.h"@implementation AppStatus@synthesize contextStr = _contextStr;static AppStatus *_instance = nil;+(AppStatus *)shareInstance{ if (_instance == nil) { _instance = [[super alloc]init]; } return _instance;}-(id)init{ if (self = [super init]) { } return self;}@end
#import "RootViewControllerFour.h"#import "AppStatus.h"#import "DetailViewControllerFour.h"@interface RootViewControllerFour ()@property (nonatomic, strong) UILabel *label;@property (nonatomic, strong) UITextField *textField;@end@implementation RootViewControllerFour- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor whiteColor]; self.title = @"单例传值"; UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; btn.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds) -40, 40); [btn setTitle:@"Push" forState:UIControlStateNormal]; btn.backgroundColor = [UIColor redColor]; [btn addTarget:self action:@selector(pushAction:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn]; [self.view addSubview:self.textField]; self.label.frame = CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) -40, 40); self.label.backgroundColor = [UIColor greenColor]; [self.view addSubview:self.label];}-(void)viewWillAppear:(BOOL)animated { if ([AppStatus shareInstance].contextStr.length !=0) { self.label.text = [AppStatus shareInstance].contextStr; } else { self.label.text = @"用于现实后面页面传递过来的值"; }}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(UITextField *)textField { if (!_textField) { _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 200, CGRectGetWidth(self.view.bounds)-40, 40)]; } _textField.placeholder = @"请输入内容"; _textField.backgroundColor = [UIColor purpleColor]; _textField.textColor = [UIColor whiteColor]; return _textField;}-(void)pushAction:(id)sender{// _textField = (UITextField *)[self.view viewWithTag:1000]; //单例传值 将要传递的信息存入单例中(共享中) // [[AppStatus shareInstance]setContextStr:tf.text]; 跟下面这种写法是等价的 [AppStatus shareInstance].contextStr = _textField.text; //导航push到下一个页面 //pushViewController 入栈引用计数+1,且控制权归系统 DetailViewControllerFour *detailViewController = [[DetailViewControllerFour alloc]init]; //导航push到下一个页面 [self.navigationController pushViewController:detailViewController animated:YES]; }#pragma mark - Getter & SetterLabelGetter(label, NSTextAlignmentCenter, ColorFromRGB(0xffffff), [UIFont systemFontOfSize:15])
#import "DetailViewControllerFour.h"#import "AppStatus.h"@interface DetailViewControllerFour ()@property (nonatomic, strong) UILabel *label;@property (nonatomic, strong) UITextField *textField;@end@implementation DetailViewControllerFour- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor whiteColor]; self.label.frame = CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) -40, 40); self.label.backgroundColor = [UIColor greenColor]; [self.view addSubview:self.label]; self.textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 200, CGRectGetWidth(self.view.bounds) -40, 40)]; self.textField.placeholder = @"请输入内容"; self.textField.backgroundColor = [UIColor purpleColor]; self.textField.textColor = [UIColor whiteColor]; [self.view addSubview:self.textField]; UIButton *button =[UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds) -40, 40); button.backgroundColor = [UIColor redColor]; [button setTitle:@"发送" forState:UIControlStateNormal]; [button addTarget:self action:@selector(doneAction:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(void)viewWillAppear:(BOOL)animated { if ([AppStatus shareInstance].contextStr.length !=0) { self.label.text = [AppStatus shareInstance].contextStr; } else { self.label.text = @"用于现实前面页面传递过来的值"; }}//pop回前一个页面-(void)doneAction:(id)sender { //单例传值 [AppStatus shareInstance].contextStr = _textField.text; [self.navigationController popViewControllerAnimated:YES];}#pragma mark - Getter & SetterLabelGetter(label, NSTextAlignmentCenter, ColorFromRGB(0xffffff), [UIFont systemFontOfSize:15])
(五)通知传值
实践方案:第一个界面中的lable显示第二个界面textField中输入的文本
实践步骤:
首先我们建立一个RootViewControllers和一个DetailViewControllers(root页面的label显示detail页面textField输入的内容),首先我们RootViewController里面注册一个通知监听,并在页面消失时移除该通知(注册与移除需要对应)
#import "RootViewControllerFive.h"#import "DetailViewControllerFive.h"#define xbyNotification @"labelChange"@interface RootViewControllerFive ()@property (nonatomic, strong) UILabel *label;@end@implementation RootViewControllerFive- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor greenColor]; self.title = @"通知传值"; [self.view addSubview:self.label]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds)-40, 40); [button setTitle:@"点击" forState:UIControlStateNormal]; [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside]; button.backgroundColor = [UIColor blueColor]; [self.view addSubview:button];}-(void)viewWillAppear:(BOOL)animated { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(labelTextChange:) name:xbyNotification object:nil];}//一开始准备在这移除消息通知,结果GG了,啥通知都收不到//-(void)viewWillDisappear:(BOOL)animated {// [super viewDidDisappear:animated];// [[NSNotificationCenter defaultCenter] removeObserver:self];//}//放在这就好了-(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self];}-(UILabel *)label { if (!_label) { _label = [[UILabel alloc ] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds)-40, 40)]; _label.textAlignment = NSTextAlignmentCenter; _label.backgroundColor = [UIColor purpleColor]; _label.text = @"等待接收通知消息"; _label.textColor = [UIColor whiteColor]; } return _label;}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(void)clickAction:(id)sender { [self.navigationController pushViewController:[DetailViewControllerFive new] animated:NO];}-(void)labelTextChange:(NSNotification *)sender { NSDictionary *dic = sender.userInfo; self.label.text = dic[@"info"];// NSLog(@"收到通知");}
点击按钮时发送通知
#import "DetailViewControllerFive.h"#define xbyNotification @"labelChange"@interface DetailViewControllerFive ()@property (nonatomic, strong) UITextField *textField;@end@implementation DetailViewControllerFive- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self.view addSubview:self.textField]; self.view.backgroundColor = [UIColor whiteColor]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds)-40, 40); [button setTitle:@"发送通知" forState:UIControlStateNormal]; button.backgroundColor = [UIColor redColor]; [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(UITextField *)textField { if (!_textField) { _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) - 40, 40)]; } _textField.placeholder = @"请输入内容"; _textField.backgroundColor = [UIColor greenColor]; return _textField;}-(void)clickAction:(id)sender { [[NSNotificationCenter defaultCenter] postNotificationName:xbyNotification object:self userInfo:@{@"info":_textField.text}]; [self.navigationController popViewControllerAnimated:NO];}
小结:注册通知与移除通知需要一一对应,同时通知名称要相同,才能收到该通知发送的消息。
Demo下载
- iOS五种页面传值方式
- iOS五种页面传值方式
- iOS 页面传值4种方式(一) 之全局变量
- iOS 页面间的传值方式
- iOS 页面之间的传值方式
- iOS-常见的页面传值方式
- jsp五种页面跳转的方式
- JSP五种页面跳转方式
- HTML页面跳转的五种方式
- HTML页面跳转的五种方式
- 五种方式实现Flex页面跳转
- ios线程的五种使用方式
- iOS五种本地缓存数据方式
- iOS 用delegate方式实现页面之间的传值
- IOS页面跳转的三种方式
- IOS页面切换的几种方式
- iOS页面间传值的两种方式
- iOS 页面跳转方式
- xml
- 负载均衡之IP
- [vim实用技巧读书笔记] vim中的模式以及其中的技巧
- linux安装rabbitMQ
- IP地址的问题
- iOS五种页面传值方式
- Bootstrap响应式框架初学准备工作
- spacemacs shell layer
- Receiver里面启动dialog引发的一系列错误解决(SYSTEM_ALERT_WINDOW)
- 【leetCode】 Count of Smaller Numbers After Self
- 一号信令详细介绍
- 浅说二叉树路径和
- bzoj 1006: [HNOI2008]神奇的国度
- struts2参数封装