最近重新整理了有关控制器之间传值的方式,主要是解决部分同学只懂得storyboard跳转或者只懂得代码跳转,案例一讲详解两种不同方式,案例二三就不再重复叙述.
原则:
1.接收方一定要有属性去接收
2.传递方需要拿到接收方,进行赋值
ONE:正向传值(顺传)
A 上一级控制器 (ex:CYContact)
B 下一级控制器 (ex: CYEditViewController)
策略: 1.上一级控制器传递给下一级控制器
2.传递方需要拿到接收方,进行直接赋值
1.1 storyboard
// 准备好segue线之后,跳转之前会调用
A:上一级控制器
// 做一些数据之间的传值
1 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ |
B:下一级控制器1
2
3
4
5
6#import <UIKit/UIKit.h>
@class CYContact;
@interface CYEditViewController : UIViewController
/** 用于存储联系人页传来的模型 */
@property (strong, nonatomic) CYContact * contactModel;
@end
1.2 纯代码
例如present到下一个控制器
A:1
2
3
4CYEditViewController *editVc = [CYEditViewController new];
editVc.contactModel = self.contactArr[indexPath.row];
UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:editVC];
[self presentViewController:vc animated:YES completion:nil];
B:1
2
3
4
5
6#import <UIKit/UIKit.h>
@class CYContact;
@interface CYEditViewController : UIViewController
/** 用于存储联系人页传来的模型 */
@property (strong, nonatomic) CYContact * contactModel;
@end
逆传:下一级控制器传递给上一级控制器
策略:使用代理,上一级控制器作为下一级控制器的代理,监听下一级控制器做的事情
A:
//1.遵守协议1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36@interface CYContactViewController ()<CYAddViewControllerDelegate>
**//2.设置代理为self控制器**
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
CYXAddViewController *addVc = segue.destinationViewController;
addVc.delegate = self;
}
**//3.实现代理方法**
- (void)addViewController:(CYAddViewController *)addVc didAddContact:(CYContact *)contact{
[self.contactArr addObject:contact];
[self.tableView reloadData];
}
B:
下一级控制器(传递方)
.h 文件:
#import <UIKit/UIKit.h>
@class CYContact,CYAddViewController;
@protocol CYAddViewControllerDelegate<NSObject>
@optional
**//1.定义代理方法**#
- (void)addViewController:(CYXAddViewController *)addVc didAddContact:(CYContact *)contact;
@end
@interface CYAddViewController : UIViewController
**//2.声明代理属性**
@property (nonatomic,weak) id<CYXAddViewControllerDelegate> delegate;
@end
.m 文件:
@implementation CYXAddViewController
逆传其他方式
// (1)在跳转之前,在传递方把接收方先保存起来
// (2)等需要真的给接收方传值的时候,直接拿到它传值
// 点击添加按钮的时候调用
1.代理
1 | - (IBAction)addContact:(id)sender { |
2.block
B:
typedef void (^ablock)(NSString *str);
@property (nonatomic, copy) ablock block;
在B试图控制器中,当输入名字,点击对应的确定按钮后:
- (IBAction)blockMethod:(id)sender {
if ([self notEmpty]) {
if (self.block) {
self.block(self.nameTextField.text);
[self dismissViewControllerAnimated:YES completion:nil];
}
}else{
[self showAlert];
}
}
A:在A试图显示,回调block
- (IBAction)showSecondWithBlock:(id)sender {
SecondViewController *second = [[SecondViewController alloc] initWithNibName:@'SecondViewController'bundle:nil];
[self presentViewController:second animated:YES completion:nil];
second.block = ^(NSString *str){
self.nameLabel.text = str;
};
}