本文簡單介紹幾種界面通信的方式,給出相應的示例丁屎。
1. 屬性傳值
屬性傳值是最簡單的一種傳值方式负饲,通常用于從前向后傳值瘫筐,即在第二個視圖控制器獲得第一個視圖控制器的部分信息蜜暑。
示例:創(chuàng)建兩個UIViewController,在第一個頁面的UITextField里輸入文字策肝,跳轉到第二個頁面之后肛捍,在第二個頁面的UILabel上顯示出來。
第一個頁面:
FirstViewController.m文件:
#import "FirstViewController.h"
#import "SecondViewController.h"
@interface FirstViewController ()
@property (nonatomic, strong) UITextField *firstTextField;
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor cyanColor];
self.navigationItem.title = @"第一頁";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"下一頁" style:UIBarButtonItemStyleDone target:self action:@selector(nextVC:)];
self.firstTextField = [[UITextField alloc] initWithFrame:CGRectMake(100, 200, 214, 40)];
_firstTextField.backgroundColor = [UIColor whiteColor];
_firstTextField.placeholder = @"輸入要傳入下一頁面的值";
[self.view addSubview:_firstTextField];
}
在觸發(fā)的點擊事件中 將第一個頁面的輸入框中輸入的信息賦值給第二個頁面的label之众,然后跳轉到第二個頁面:
-(void)nextVC:(UIBarButtonItem *)sender{
SecondViewController *secondVC = [[SecondViewController alloc] init];
secondVC.stringFromFirstVC = _firstTextField.text;
[self.navigationController pushViewController:secondVC animated:YES];
}
@end
第二個頁面:
SecondViewController.h文件:
暴露一個屬性拙毫,用于傳值。
#import <UIKit/UIKit.h>
@interface SecondViewController : UIViewController
@property (nonatomic, strong) NSString *stringFromFirstVC;
@end
SecondViewController.m文件:
#import "SecondViewController.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"第二頁";
self.view.backgroundColor = [UIColor lightGrayColor];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStyleDone target:self action:@selector(back:)];
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(100, 200, 214, 40)];
label.text = self.stringFromFirstVC;
[self.view addSubview:label];
}
-(void)back:(UIBarButtonItem *)sender{
[self.navigationController popViewControllerAnimated:YES];
}
@end
2. 代理傳值
定義一個用來傳值的協(xié)議棺禾,設置代理去執(zhí)行傳值缀蹄。
示例:創(chuàng)建兩個UIViewController,在第二個頁面的UITextField里輸入文字膘婶,跳轉回第一個頁面之后缺前,在第一個頁面的UILabel上顯示出來。
第一個頁面:
FirstViewController.m文件:
#import "FirstViewController.h"
#import "SecondViewController.h"
@interface FirstViewController ()<PassValueDelegate> //遵守協(xié)議
@property (nonatomic, strong) UILabel *label;
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor cyanColor];
self.navigationItem.title = @"第一頁";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"下一頁" style:UIBarButtonItemStyleDone target:self action:@selector(nextVC:)];
self.label = [[UILabel alloc] initWithFrame:CGRectMake(100, 300, 214, 40)];
_label.backgroundColor = [UIColor yellowColor];
[self.view addSubview:_label];
}
觸發(fā)的點擊事件:設置代理后跳轉到第二個頁面:
-(void)nextVC:(UIBarButtonItem *)sender{
SecondViewController *secondVC = [[SecondViewController alloc] init];
//將第一個頁面指定為第二個頁面的代理!
secondVC.delegate = self;
[self.navigationController pushViewController:secondVC animated:YES];
}
實現(xiàn)代理方法:
-(void)passValue:(NSString *)value{
_label.text = value;
}
@end
第二個頁面:
SecondViewController.h文件:
定義一個用來傳值的協(xié)議衅码,聲明代理屬性
#import <UIKit/UIKit.h>
@protocol PassValueDelegate <NSObject>
-(void)passValue:(NSString *)value;
@end
@interface SecondViewController : UIViewController
//聲明代理屬性,其中<PassValueDelegate>指定其遵守的協(xié)議
@property(nonatomic,assign)id<PassValueDelegate>delegate;
@end
SecondViewController.m文件:
#import "SecondViewController.h"
@interface SecondViewController ()
@property (nonatomic, strong) UITextField *textField;
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"第二頁";
self.view.backgroundColor = [UIColor lightGrayColor];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStyleDone target:self action:@selector(back:)];
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 300, 214, 40)];
_textField.backgroundColor = [UIColor whiteColor];
_textField.placeholder = @"輸入要傳入上一頁面的值";
[self.view addSubview:_textField];
}
-(void)back:(UIBarButtonItem *)sender{
//代理去執(zhí)行傳值!!!
[_delegate passValue:_textField.text];
//跳轉回第一頁
[self.navigationController popViewControllerAnimated:YES];
}
3. block傳值
使用block實現(xiàn)回調功能的優(yōu)點是比較清晰古胆,簡化代碼肆良。
注意:在block實現(xiàn)部分筛璧,不要直接使用self逸绎、實例變量、屬性夭谤,因為會造成循環(huán)引用棺牧。
示例:創(chuàng)建兩個UIViewController,在第二個頁面的UITextField里輸入文字朗儒,跳轉回第一個頁面之后颊乘,在第一個頁面的UILabel上顯示出來采呐。
第一個頁面:
FirstViewController.m文件:
#import "FirstViewController.h"
#import "SecondViewController.h"
@interface FirstViewController ()
@property(nonatomic,strong)UILabel *label;
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor =[UIColor blueColor];
self.label = [[UILabel alloc] initWithFrame:CGRectMake(100, 300, 214, 50)];
_label.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_label];
}
添加觸摸事件,模態(tài)出下一個視圖(用別的方式也可以)
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
SecondViewController *secondVC = [[SecondViewController alloc] init];
//block的實現(xiàn)
__weak FirstViewController *temp = self;
secondVC.block = ^(NSString *string){
//通過回調將傳進來的字符串賦值給_label
temp.label.text = string;
};
//跳轉到第二個頁面
[self presentViewController:secondVC animated:YES completion:nil];
}
@end
第二個頁面:
SecondViewController.h文件:
在這里定義一個block陕凹,聲明block屬性恳不。
ARC中block的語義設置使用strong即可檩小,MRC中block的語義設置是copy(把block從棧區(qū)拷貝到堆區(qū),使用完之后烟勋,在dealloc中釋放)规求。
#import <UIKit/UIKit.h>
//定義有參無返回值的匿名函數(shù)(傳遞字符串)
typedef void (^PassValueBlock)(NSString *);
@interface SecondViewController : UIViewController
@property (nonatomic, strong) PassValueBlock block;
@end
SecondViewController.m文件:
#import "SecondViewController.h"
@interface SecondViewController ()
@property (nonatomic, strong) UITextField *textField;
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 300, 214, 50)];
_textField.placeholder = @"block傳值";
_textField.backgroundColor = [UIColor orangeColor];
[self.view addSubview:_textField];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//調用block
self.block(_textField.text);
[self dismissViewControllerAnimated:YES completion:nil];
}
@end