今天看了一下ios 页面传值的方式大致分为四种:
今天试了一下前三种,在这里记录一下
下面示例是有两个页面,每个页面都有一个按钮Button,点击第一个页面的按钮回调到第二个页面,再点击第二个页面回跳转道第一个页面,第一个按钮的标题变为第二个按钮传回的值。
代理delegate
代理似乎是我的心结,能用API 但是就是不会自己写,这也是今天会写传值的原因。
假设两个页面传值,协议类应该写在哪,代理应该定义在那个页面?
总结的时候我觉得可以这样来想:第二个页面想要修改第一个页面的值,但是他没办法做到,所以他需要一个代理来帮助它修改,所以代理需要定义在第二个页面。第一个页面需要支持代理。
第一个页面:
@interface frontVC : UIViewController<change> @property (weak, nonatomic) IBOutlet UIButton *frontBtn; @end
#import "frontVC.h" @interface frontVC () { realendVC *realendvc;//第二个页面 } @end @implementation frontVC - (void)viewDidLoad { [super viewDidLoad]; //从storyboard中获得第二个页面 UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; realendvc = [storyboard instantiateViewControllerWithIdentifier:@"second"]; //设置代理 realendvc.delegate = self; } //按钮点击事件 - (IBAction)click:(id)sender { [self.navigationController pushViewController:realendvc animated:YES]; } //代理方法 - (void)changebutton:(NSString *)string { [_frontBtn setTitle:string forState:UIControlStateNormal]; } @end
@protocol change <NSObject> - (void) changebutton:(NSString *)string; @end @interface realendVC : UIViewController @property (weak, nonatomic) IBOutlet UIButton *realendBtn; @property (nonatomic,weak) id<change> delegate; @end
#import "realendVC.h" @interface realendVC () @end @implementation realendVC - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)click:(id)sender { [self.navigationController popViewControllerAnimated:YES]; if (self.delegate) { [self.delegate changebutton:@"成功"]; } } @end
block
第一个页面
#import <UIKit/UIKit.h> #import "realendVC.h" @interface frontVC : UIViewController @property (weak, nonatomic) IBOutlet UIButton *frontBtn; @end
#import "frontVC.h" @interface frontVC () { realendVC *realendvc;//第二个页面 } @end @implementation frontVC - (void)viewDidLoad { [super viewDidLoad]; //从storyboard中获得第二个页面 UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; realendvc = [storyboard instantiateViewControllerWithIdentifier:@"second"]; //在block中允许访问变量,但不允许修改,需要加上下面一句代码 __block UIButton * button = _frontBtn; realendvc.myblock = ^(NSString *string) { [button setTitle:string forState:UIControlStateNormal]; }; } //按钮点击事件 - (IBAction)click:(id)sender { [self.navigationController pushViewController:realendvc animated:YES]; } @end
#import <UIKit/UIKit.h> typedef void(^Myblock) (NSString *); @interface realendVC : UIViewController @property (weak, nonatomic) IBOutlet UIButton *realendBtn; @property (copy,nonatomic) Myblock myblock; @end
#import "realendVC.h" @interface realendVC () @end @implementation realendVC - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)click:(id)sender { [self.navigationController popViewControllerAnimated:YES]; self.myblock(@"成功"); } @end
第一个页面
#import <UIKit/UIKit.h> #import "realendVC.h" @interface frontVC : UIViewController @property (weak, nonatomic) IBOutlet UIButton *frontBtn; @end
#import "frontVC.h" @interface frontVC () { realendVC *realendvc;//第二个页面 } @end @implementation frontVC - (void)viewDidLoad { [super viewDidLoad]; //从storyboard中获得第二个页面 UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; realendvc = [storyboard instantiateViewControllerWithIdentifier:@"second"]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(change:) name:@"button"object:nil]; } //通知调用事件 - (void)change:(NSNotification *)notification { [_frontBtn setTitle:(NSString *)[notification object] forState:UIControlStateNormal]; } //按钮点击事件 - (IBAction)click:(id)sender { [self.navigationController pushViewController:realendvc animated:YES]; } @end
#import <UIKit/UIKit.h> @interface realendVC : UIViewController @property (weak, nonatomic) IBOutlet UIButton *realendBtn; @end
#import "realendVC.h" @interface realendVC () @end @implementation realendVC - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)click:(id)sender { [self.navigationController popViewControllerAnimated:YES]; [[NSNotificationCenter defaultCenter] postNotificationName:@"button" object:@"成功"]; } @end