總結iOS 頁面間五種傳值(屬性,代理 , block,單例,通知)

廢話不多說下面我們就簡單介紹下頁面間常用的幾種傳值方式,希望能給初學者帶來幫助:

注: 文中 ,第一個界面為FirstViewController,第二個界面為SecondViewController

(-)屬性傳值

屬性傳值(場景)一般用于正向傳值,即第一個界面?zhèn)髦到o第二個界面

屬性傳值是這幾大傳值中最簡單的傳值方式只需要要記住兩點:
1.要在接收值的界面(SecondViewController)中聲明屬性即文中: labelString
2.要在跳轉界面的同時將要傳的賦值給下個控制器對象的屬性即文中的這個操作: secondVc.labelString =textF.text;

簡單的傳值代碼如下:
FirstViewController
#import "FirstViewController.h"
#import "SecondViewController.h"
@interface FirstViewController ()
{
    UITextField * textF;
}
@end

@implementation FirstViewController

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor =[UIColor whiteColor];
[self creatUI];
}

-(void)creatUI{
//創(chuàng)建輸入框
textF = [[UITextField alloc]init];
textF.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
textF.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:textF];
//創(chuàng)建跳轉下個界面的按鈕
UIButton * PushBtn = [UIButton buttonWithType:(UIButtonTypeSystem)];
PushBtn.frame = CGRectMake(0, 140, self.view.frame.size.width, 30);
[PushBtn setTitle:@"Push" forState:(UIControlStateNormal)];
[PushBtn addTarget:self action:@selector(PushClick:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:PushBtn];

}

//按鈕點擊事件
-(void)PushClick:(UIButton*)sender{

SecondViewController * secondVc = [[SecondViewController alloc]init];
 //賦值給下個控制器的屬性
secondVc.labelString =textF.text;
[self.navigationController pushViewController:secondVc animated:YES];

}
SecondViewController
#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController
//聲明屬性:用來接收上個界面?zhèn)鬟^來的值
@property (nonatomic,copy) NSString *labelString;
@end


#import "SecondViewController.h"

@implementation SecondViewController

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UILabel *label = [[UILabel alloc]init];
label.frame =CGRectMake(0, 100, self.view.frame.size.width, 30);
//在標簽上展示上個界面?zhèn)鬟^來的值
label.text  = _labelString;
[self.view addSubview:label];
}

(二)Block傳值

block傳值(場景)一般用于逆向傳值,即第二個界面?zhèn)髦到o第一個界面

block的用法很多對于初學者來說是個難點,對于傳值來說看了本文你可能會覺的并沒有那么難,對比屬性傳值,我們也需要記住兩點:
1.要在第二個界面(SecondViewController.h)定義一個Block:
#import <UIKit/UIKit.h>
typedef void (^PushBlock)(NSString*);
@interface SecondViewController : UIViewController
@property (nonatomic,strong)PushBlock pushValueString;
@endpushValueString;
2.要在第一個界面(FirstViewController.m)跳轉第二個界面的方法中我們?yōu)閎lock屬性賦值完成block傳值:

-(void)PushClick:(UIButton*)sender{

SecondViewController * secondVc = [[SecondViewController alloc]init
secondVc.pushValueString = ^(NSString *str){
    textF.text =str;
} ;

[self.navigationController pushViewController:secondVc animated:YES];

}
Block傳值完整代碼如下:
FirstViewController
#import "FirstViewController.h"
#import "SecondViewController.h"
@interface FirstViewController ()
{
UITextField * textF;
}
@end

@implementation FirstViewController

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor =[UIColor whiteColor];
[self creatUI];
}

-(void)creatUI{
textF = [[UITextField alloc]init];
textF.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
textF.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:textF];

UIButton * PushBtn = [UIButton buttonWithType:(UIButtonTypeSystem)];
PushBtn.frame = CGRectMake(0, 140, self.view.frame.size.width, 30);
[PushBtn setTitle:@"Push" forState:(UIControlStateNormal)];
[PushBtn addTarget:self action:@selector(PushClick:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:PushBtn];

}
//跳轉下個界面點擊事件
-(void)PushClick:(UIButton*)sender{

SecondViewController * secondVc = [[SecondViewController alloc]init];
//核心代碼為block屬性賦值
secondVc.pushValueString = ^(NSString *str){
    textF.text =str;
} ;

[self.navigationController pushViewController:secondVc animated:YES];

}
SecondViewController
#import <UIKit/UIKit.h>
typedef void (^PushBlock)(NSString*);
@interface SecondViewController : UIViewController
@property (nonatomic,strong)PushBlock pushValueString;
@end


#import "SecondViewController.h"

@interface SecondViewController ()
{

UITextField * textF;
NSString * textFString;
}
@end

@implementation SecondViewController

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
textF = [[UITextField alloc]init];
textF.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
textF.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:textF];

UIButton * Backbtn = [UIButton buttonWithType:(UIButtonTypeSystem)];

Backbtn.frame  =CGRectMake(0, 140, self.view.frame.size.width, 30);

[Backbtn addTarget:self action:@selector(backClick:) forControlEvents:(UIControlEventTouchUpInside)];
[Backbtn setTitle:@"back" forState:(UIControlStateNormal)];
[self.view addSubview:Backbtn];
}
//返回第一個界面并將值帶入
-(void)backClick:(UIButton*)sender{
//核心代碼
_pushValueString(textF.text);
[self.navigationController popViewControllerAnimated:YES];
}

(三)代理傳值

代理傳值(場景)一般用于逆向傳值,即第二個界面?zhèn)髦到o第一個界面

FirstViewController頁面push到SecondViewController頁面,如果SecondViewController頁面的信息想回傳(回調)到FirstViewController頁面,用代理傳值,其中SecondViewController定義協(xié)議和聲明代理,FirstViewController確認并實現(xiàn)代理,FirstViewController作為SecondViewController的代理
對于代理傳值我們要記住如下記步操作:
第一步:首先,在SecondViewController.h中
(1).定義協(xié)議
(2).設置協(xié)議中的方法
(3).聲明代理
然后,在SecondViewController.m中
(1).為其綁定相應方法
第二步:在FirstViewController.m中
(1).設置代理
(2).服從協(xié)議

完整代理傳值代碼如下:
SecondViewController
//首先在SecondViewController.h中創(chuàng)建協(xié)議方法
#import <UIKit/UIKit.h>
@class SecondViewController;
//定義協(xié)議
@protocol PushValueDelegate<NSObject>
@optional
//設置協(xié)議中的方法
-(void)viewController:(SecondViewController*)ViewController didPushVlaueWithInfo:(id)info;
@end
@interface SecondViewController : UIViewController
//聲明代理
@property (nonatomic,assign)id<PushValueDelegate>delegate;
@end


//然后,在SecondViewController.m中我們判定代理對象存在時,為其綁定相應方法
#import "SecondViewController.h"
@interface SecondViewController ()
{
UITextField * textF;
NSString * textFString;
}
@end
@implementation SecondViewController
-(void)viewWillDisappear:(BOOL)animated{
//設置視圖將要消失時.通過代理傳值
//判斷代理是否存在,并且設置代理能夠響應代理方法時,才執(zhí)行代理方法
if (self.delegate && [self.delegate respondsToSelector:@selector(viewController:didPushVlaueWithInfo:)]) {
    [self.delegate viewController:self didPushVlaueWithInfo:textF.text];
}
}

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
textF = [[UITextField alloc]init];
textF.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
textF.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:textF];

}
FirstViewController
#import "FirstViewController.h"
#import "SecondViewController.h"
//服從協(xié)議
@interface FirstViewController ()<PushValueDelegate>
{
  UITextField * textF;
}
@end

@implementation FirstViewController

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor =[UIColor whiteColor];
[self creatUI];
  }

-(void)creatUI{
textF = [[UITextField alloc]init];
textF.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
textF.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:textF];

UIButton * PushBtn = [UIButton buttonWithType:(UIButtonTypeSystem)];
PushBtn.frame = CGRectMake(0, 140, self.view.frame.size.width, 30);
[PushBtn setTitle:@"Push" forState:(UIControlStateNormal)];
[PushBtn addTarget:self action:@selector(PushClick:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:PushBtn];

}
-(void)PushClick:(UIButton*)sender{

SecondViewController * secondVc = [[SecondViewController alloc]init];
//設置代理
secondVc.delegate =self;

[self.navigationController pushViewController:secondVc animated:YES];

}
//實現(xiàn)代理方法
-(void)viewController:(SecondViewController*)ViewController didPushVlaueWithInfo:(id)info{

textF.text = info;

}

(四)單例傳值

單例可以保證某個類的實例在程序中是唯一的,便于進行資源和數(shù)據(jù)的共享。

單例的實現(xiàn):
(1)新建一個普通的類,假設名字為People 在People.h中聲明一個類方法,到時候使用該類方法(注意:一定是類方法,而不是實例方法)可以創(chuàng)建該類的唯一的一個實例

#import "Peopel.h"
@implementation People
{
  NSString *_eat;
 }
@property(nonatomic,retain)NSString *eat;
+(Peopel*)shareInstance;
@end

(2)在Peopel .m中需要實現(xiàn)sharedInstance方法和你其他的業(yè)務邏輯
#import "Peopel.h"
//static聲明一個類的靜態(tài)實例;
static Peopel instrance = nil;
@implementation Peopel
//使用類方法生成這個類唯一的實例
+(Peopel
)shareInstance{

if (instrance == nil) {
    instrance = [[super alloc]init];
  }
return instrance;

}
@end

注意:一定要聲明一個static的靜態(tài)變量。以后創(chuàng)建類的唯一實例就使用sharedInstance方法,而不是使用alloc ,init.

下面為單例傳值的簡單使用(完整代碼):
FirstViewController
#import "FirstViewController.h"
#import "SecondViewController.h"
#import"Peopel.h"

@interface FirstViewController ()
{
  UITextField * textF;
}
@end

@implementation FirstViewController

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor =[UIColor whiteColor];
[self creatUI];

}
//接收由第二個界面pop回時textF里的數(shù)據(jù)值
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
textF.text=[Peopel shareInstance].eat;
}

-(void)creatUI{
textF = [[UITextField alloc]init];
textF.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
textF.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:textF];
UIButton * PushBtn = [UIButton buttonWithType:(UIButtonTypeSystem)];
PushBtn.frame = CGRectMake(0, 140, self.view.frame.size.width, 30);
[PushBtn setTitle:@"Push" forState:(UIControlStateNormal)];
[PushBtn addTarget:self action:@selector(PushClick:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:PushBtn];

}
-(void)PushClick:(UIButton*)sender{
//跳轉下個界面的同時為單例屬性賦值
 [[Peopel shareInstance]setEat:textF.text];
SecondViewController * secondVc = [[SecondViewController alloc]init];
[self.navigationController pushViewController:secondVc animated:YES];    
}
SecondViewController
#import "SecondViewController.h"
#import "Peopel.h"
@interface SecondViewController ()
{
UITextField * textF;
NSString * textFString;
}
@end

@implementation SecondViewController
-(void)viewWillDisappear:(BOOL)animated{
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
textF.text = [Peopel shareInstance].eat;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
textF = [[UITextField alloc]init];
textF.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
textF.borderStyle = UITextBorderStyleRoundedRect;
textF.text = [Peopel shareInstance].eat;
[self.view addSubview:textF];
//返回按鈕
UIButton * Backbtn = [UIButton buttonWithType:(UIButtonTypeSystem)];
Backbtn.frame  =CGRectMake(0, 140, self.view.frame.size.width, 30);
[Backbtn addTarget:self action:@selector(backClick:) forControlEvents:(UIControlEventTouchUpInside)];
[Backbtn setTitle:@"back" forState:(UIControlStateNormal)];
[self.view addSubview:Backbtn];
}

-(void)backClick:(UIButton*)sender{
//返回時為單例屬性賦值
[Peopel shareInstance].eat = textF.text;
[self.navigationController popViewControllerAnimated:YES];
}

(五)通知傳值

誰要監(jiān)聽值的變化,誰就注冊通知 特別要注意,通知的接受者必須存在這一條件

1、注冊通知
2、通知中心發(fā)送一條消息通知,其中name前后一定要一樣
3、實現(xiàn)通知中心內部的方法,并實現(xiàn)傳值
4、消息發(fā)送完,要移除掉。(頁面將要消失的時候)

通知傳值的簡單代碼如下:

代碼為第二個界面?zhèn)髦档降谝粋€界面的實現(xiàn):

FirstViewController
#import "FirstViewController.h"
#import "SecondViewController.h"

@interface FirstViewController ()
{
  UITextField * textF;
}
@end

@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor =[UIColor whiteColor];
[self creatUI];
/**
 adObserver:注冊監(jiān)聽者,一般都是控制器本身去監(jiān)聽一個通知
 selector :當監(jiān)聽到通知的時候執(zhí)行的方法
 name :通知的名字,要和發(fā)送的通知的對象的名字一致
 object: nil
 */
//注冊監(jiān)聽者
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(ChangeTextFText:) name:@"ChangeValue" object:nil];

}
-(void)ChangeTextFText:(NSNotification*)notification{
NSDictionary * dic = notification.userInfo;
NSLog(@"%@",dic);
textF.text = dic[@"Value"];
}

-(void)creatUI{
textF = [[UITextField alloc]init];
textF.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
textF.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:textF];
UIButton * PushBtn = [UIButton buttonWithType:(UIButtonTypeSystem)];
PushBtn.frame = CGRectMake(0, 140, self.view.frame.size.width, 30);
[PushBtn setTitle:@"Push" forState:(UIControlStateNormal)];
[PushBtn addTarget:self action:@selector(PushClick:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:PushBtn];

}
-(void)PushClick:(UIButton*)sender{
SecondViewController * secondVc = [[SecondViewController alloc]init];
[self.navigationController pushViewController:secondVc animated:YES];
}

//移除控制器上所有監(jiān)聽的通知
-(void)dealloc{
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
SecondViewController
#import "SecondViewController.h"

@interface SecondViewController ()
{

  UITextField * textF;
}
@end

@implementation SecondViewController
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
textF = [[UITextField alloc]init];
textF.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
textF.borderStyle = UITextBorderStyleRoundedRect;

[self.view addSubview:textF];

UIButton * Backbtn = [UIButton buttonWithType:(UIButtonTypeSystem)];

Backbtn.frame  =CGRectMake(0, 140, self.view.frame.size.width, 30);

[Backbtn addTarget:self action:@selector(backClick:) forControlEvents:(UIControlEventTouchUpInside)];
[Backbtn setTitle:@"back" forState:(UIControlStateNormal)];
[self.view addSubview:Backbtn];
}

-(void)backClick:(UIButton*)sender{
//發(fā)送通知
  [[NSNotificationCenter defaultCenter]postNotificationName:@"ChangeValue" object:nil userInfo:@{@"Value":textF.text}];
[self.navigationController popViewControllerAnimated:YES];
}

本講完結:希望能給朋友們的學習帶來幫助

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容