iOS页面间几种传值方式
来源:互联网 发布:淘宝店铺有访客没订单 编辑:程序博客网 时间:2024/06/05 06:55
传值方法
- 属性
- 方法
- 代理
- block
- 通知
- 单例
页面间传值有八大传值方式,下面我就简单介绍下页面间常用的传值方式,但对于每种方式的详细介绍由于内容很多,我会把每种方式单独列出作为一篇文章详细介绍,本文不做详细说明
属性传值
第二个界面(DetailViewController)中的label显示第一个界面(RootViewController)textField中的文本
首先我们建立一个RootViewController和一个DetailViewController,在DetailViewController中声明一个textString属性,用于接收传过来的字符串。
#import <UIKit/UIKit.h>@interface DetailViewController : UIViewController @property(nonatomic,copy) NSString *textString://属性传值@end
同时创建一个Label用来显示传过的字符串
#import "DetailViewController.h"@interface DetailViewController()@end@implementation DetailViewController - (void)viewDidLoad { [super viewDidLoad]; UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) - 50, 44)]; label.backgroundColor = [UIColor grayColor]; label.font = [UIFont systemFontOfSize:20]; label.numberOfLines = 0; label.text = self.textString;//属性传值得到显示文本 [self.view addSubview:labelOne];}
在RootViewController.m文件中引入DetailViewController同时声明一个textField属性用来输入字符串
#import "RootViewController.h"#import "DetailViewController.h"@interface RootViewController ()@property(nonatomic,strong) UITextField *textField;@end@implementataion RootViewController//懒加载,重写textField的getter方法- (UITextField *)textField { if (!_textField) { _textField = [[UITextField alloc]initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) - 50, 44)]; } return _textField;}
然后在RootViewController上我们创建并添加一个button,当点击button时响应相应方法进行视图间的切换并且完成视图间的传值
- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; [self.view addSubview:self.textField]; UIButton *pushButton = [UIButton buttonWithType:UIButtonTypeCustom]; pushButton.bounds = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds) - 50, 44); pushButton.center = self.view.center; [pushButton setTitle:@"点击进入DetailVC" forState:UIControlStateNormal]; [pushButton addTarget:self action:@selector(respondsToPushButton:) forControlEvents:UIControlStateNormal]; }//pushbutton点击事件- (void)respondsToPushButton:(UIButton *)sender { DetailViewController *detailVc = [[DetailViewController alloc]init]; detailVc.textString = self.textField.text; [self.navigationController pushViewController:detailVc animated:YES];}
方法传值
需求同一中的属性传值 一样,但是要通过使用方法传值,可以直接将方法与初始化方法合并,此时当触发RootViewController的按钮点击事件并跳转到DetailViewController时,在按钮点击事件中可以直接通过DetailViewController的初始化,将值传入firstValue中:
初始化方法如下:
首先DetailViewController视图中需要有一个Label用来存储传递过来的值:
//重写初始化方法,用于传值。可以自定义初始化方法,也可以重写系统初始化方法- (instancetype)initWithFrame:(CGRect)frame String:(NSString *)str{ self = [super initWithFrame:frame]; if (self) { _label.text = str; } return self;}
方法传值:
//pushbutton点击事件- (void)respondsToPushButton:(UIButton *)sender { DetailViewController *detailVc = [[DetailViewController alloc]initWithFrame:self.view.bounds String:self.textField.text]; [self.navigationController pushViewController:detailVc animated:YES];}//这样就可以直接通过初始化方法获得传递过来的值:
代理传值
RootViewController页面push到DetailViewControllers页面,如果DetailViewController页面的信息想回传(回调)到RootViewController页面,用代理传值,其中DetailViewController定义协议和声明代理,RootViewController确认并实现代理,RootViewController作为DetailViewController的代理
首先在DetailViewController.h文件中我们创建协议方法
#import <UIKit/UIKit.h>@class DetailViewController;//DetailViewController是协议方,RootViewController是代理方@protocol DetailViewControllerDelegate <NSObject>- (void)detailViewController:(DetailViewController *)Vc didClickedButtonWithColor:(UIColor *)color;@end@interface DetailViewController : UIViewController//代理属性@property(nonatomic,assign) id<DetailViewControllerDelegate> delegate;@end
在DetailViewController的.m中我们添加一个pop返回RootViewControlelr的button,并为其添加响应事件
- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor redColor]; [self.view addSubview:self.textField]; UIButton *popButton = [UIButton buttonWithType:UIButtonTypeCustom]; popButton.bounds = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds) - 50, 44); popButton.center = self.view.center; [popButton setTitle:@"点击返回RootVc" forState:UIControlStateNormal]; [popButton addTarget:self action:@selector(respondsToPopButton:) forControlEvents:UIControlStateNormal]; }//popbutton点击事件- (void)respondsToPopButton:(UIButton *)sender { if (self.delegate && [self.delegate respondsToSelector:@selector(detailViewController:didClickedButtonWithColor:)]) { [self.delegate detailViewController:self didClickedButtonWithColor:self.view.backgroundColor]; } [self.navigationController popViewControllerAnimated:YES];}
RootViewController的.m文件中我们指定代理并让其执行代理的方法
然后在RootViewController上我们写在push到DetailViewController的方法中
//pushbutton点击事件- (void)respondsToPushButton:(UIButton *)sender { DetailViewController *detailVc = [[DetailViewController alloc]init]; //为detailVc指定代理对象 detailVc.delegate = self; detailVc.textString = self.textField.text; [self.navigationController pushViewController:detailVc animated:YES];}//实现代理方法- (void)detailViewController:(DetailViewController *)Vc didClickedButtonWithColor:(UIColor *)color{ //使用传来的color设置当前控制器视图的背景色 self.view.backgroundColor = color;}
block传值
block传值也是从第二个界面(DetailViewController)传给第一个界面(RootViewController),和代理传值方法类似
首先我们在DetailViewcontroller的.h文件中,定义block属性
#import <UIKit/UIKit.h>//第一步,定义block类型typedef void(^ColorBlock)(UIColor *);@interface DetailViewController : UIViewController//第二步,定义block属性@property(nonatomic,copy) ColorBlock colorBlock;@end
再在DetailViewcontroller的.m文件中执行block
//popbutton点击事件- (void)respondsToPopButton:(UIButton *)sender { if (_colorBlock) { _colorBlock(self.view.backgroundColor); } [self.navigationController popViewControllerAnimated:YES];}
在RootViewController的.m文件中,其他不变,在pushbutton的响应方法里我们为block属性赋值完成block传值
//pushbutton点击事件- (void)respondsToPushButton:(UIButton *)sender { DetailViewController *detailVc = [[DetailViewController alloc]init]; //在这里拿到对应控制器的block属性,实现并获得传递的参数 detail.colorBlock = ^(UIColor *color){ self.view.backgroundColor = color; }; [self.navigationController pushViewController:detailVc animated:YES];}
通知传值
要使用通知传值先要了解其基本概念
NSNotification这个类可以理解为一个消息对象,其中有三个成员变量。
这个成员变量是这个消息对象的唯一标识,用于辨别消息对象。
@property (readonly, copy) NSString *name;
这个成员变量定义一个对象,可以理解为针对某一个对象的消息。
@property (readonly, retain) id object;
这个成员变量是一个字典,可以用其来进行传值。
@property (readonly, copy) NSDictionary *userInfo;
NSNotification的初始化方法:
- (instancetype)initWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo;+ (instancetype)notificationWithName:(NSString *)aName object:(id)anObject;+ (instancetype)notificationWithName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;注意:官方文档有明确的说明,不可以使用init进行初始化
NSNotificationCenter这个类是一个通知中心,使用单例设计,每个应用程序都会有一个默认的通知中心。用于调度通知的发送的接受。
添加一个观察者,可以为它指定一个方法,名字和对象。接受到通知时,执行方法。
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;
发送通知消息的方法
- (void)postNotification:(NSNotification *)notification;- (void)postNotificationName:(NSString *)aName object:(id)anObject;- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;
移除观察者的方法
- (void)removeObserver:(id)observer;- (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;
几点注意:
1、如果发送的通知指定了object对象,那么观察者接收的通知设置的object对象与其一样,才会接收到通知,但是接收通知如果将这个参数设置为了nil,则会接收一切通知。
2、观察者的SEL函数指针可以有一个参数,参数就是发送的死奥西对象本身,可以通过这个参数取到消息对象的userInfo,实现传值。
通知不需要再页面跳转时设置代理属性或者block属性,只需要在要接收信息的地方注册通知,在传值的地方发送通知即可,但切记注册通知一定要在发送通知的代码执行之前,具体实现方法
首先,我们在需要接收通知的地方注册观察者,比如:
//获取通知中心单例对象NSNotificationCenter * center = [NSNotificationCenter defaultCenter];//添加当前类对象为一个观察者,name和object设置为nil,表示接收一切通知[center addObserver:self selector:@selector(notice:) name:@"123" object:nil];
我们可以在回调的函数中取到userInfo内容,如下:
-(void)notice:(id)sender{ NSLog(@"%@",sender);}
之后,在我们需要时发送通知消息
//创建一个消息对象NSNotification * notice = [NSNotification notificationWithName:@"123" object:nil userInfo:@{@"1":@"123"}];//发送消息[[NSNotificationCenter defaultCenter]postNotification:notice];
单例传值
单例的创建方法有很多,还有一些单例的具体创建方法请浏览我的关于单例的博客,我么这里先创建一个简单单例作为例子,开发中常用的创建简单单例方法如下:
创建一个单例类ControllerManager
首先在ControllerManager的.h文件中声明一个方法
#import <Foundation/Foundation.h>@interface ControllerManager : NSObject@property(nonatomic,copy) NSString *str;+ (ControllerManager *)shareManager;@end
在ControllerManager的.m文件中实现
#import "ControllerManager"//先初始化一个静态变量static ControllerManager *manager = nil;@implementation ControllerManager+ (ControllerManager *)shareManager { static dispatch_once_t onceToken; dispatch_once(&onceToken,^{ manager = [[ControllerManager alloc]init]; }); return manager;}@end
这样在程序其他任何地方都可以通过调用单例方法进行赋值和传值,例如在RootViewController中赋值
#import "RootViewController.h"#import "ControllerManager.h"@interface RootViewController()@end@implementation RootViewController- (void)viewDidLoad { //单例传值 将要传递的信息存入单例中 [ControllerManager shareManager].str = @"Hello World"; //等价于 [[ControllerManager shareManager]setStr:@"Hello World"];}@end
在DetailViewController中取值
#import "DetailViewController"@interface DetailViewController()@end@implementation DetailViewController- (void)viewDidLoad { UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 150, 30)]; label.text = [ControllerManager shareManager].str; [self.view addSubview:label];}@end
- iOS页面间几种传值方式
- iOS 页面跳转方式
- IOS 页面跳转方式总结
- iOS页面间传值的方式
- iOS页面的布局方式
- iOS 页面间几种传值方式(属性,代理,block,单例,通知
- IOS 页面跳转的数据传递方式
- IOS 页面跳转的数据传递方式
- IOS页面跳转的三种方式
- IOS页面切换的几种方式
- iOS开发页面之间的几种传值方式
- iOS 页面间的传值方式
- iOS页面间的几种传值方式
- iOS常见创建页面的方式
- iOS页面间传值的两种方式
- iOS页面间跳转方式总结
- ios页面间跳转方式总结
- iOS五种页面传值方式
- java的内置对象
- mydac 7.6.1.1 for delphi 10.1 berlin
- IO 输入输出 流 基本概念整理(FileInputStream,FileOutputStream)
- centos7下使用yum安装mysql
- 定制centos自动化安装ISO
- iOS页面间几种传值方式
- Git学习之路(四)——Git仓库管理
- When Does Deep Learning Work Better Than SVMs or Random Forests?
- Order by 1 的解释
- 基于深度学习的目标检测研究进展
- c++文件复制粘贴
- JavaScript初学入门一
- 呃呃呃,,,时间复杂度
- Java4Android第3课:类的引入