iOS控制器之间传值

最近重新整理了有关控制器之间传值的方式,主要是解决部分同学只懂得storyboard跳转或者只懂得代码跳转,案例一讲详解两种不同方式,案例二三就不再重复叙述.
原则:
1.接收方一定要有属性去接收
2.传递方需要拿到接收方,进行赋值

ONE:正向传值(顺传)

A 上一级控制器 (ex:CYContact)

B 下一级控制器 (ex: CYEditViewController)

策略: 1.上一级控制器传递给下一级控制器
2.传递方需要拿到接收方,进行直接赋值

1.1 storyboard

// 准备好segue线之后,跳转之前会调用
A:上一级控制器
// 做一些数据之间的传值

1
2
3
4
5
6
7
8
9
10
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
//获取目标控制器
CYEditViewController *editVc = segue.destinationViewController;
// 获取当前选中的角标
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
// 获取选中的cell对应的模型
CYContactModel *model = self.contactArr[indexPath.row];
// 传递选中的cell对应的模型
editVc.contactModel = model;
}

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
4
CYEditViewController *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
2
3
4
5
6
7
8
9
10
11
- (IBAction)addContact:(id)sender {
// 把姓名和电话文本框的内容包装成模型
CYContact *contact = [CYContact contactWithName:_nameField.text phone:_phoneField.text];

**// 3.调用代理方法,通知代理接收联系人模型**
if ([_delegate respondsToSelector:@selector(addViewController:didAddContact:)]) {
[_delegate addViewController:self didAddContact:contact];
}
// 回到上一个控制器
[self.navigationController popViewControllerAnimated:YES];
}

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;

};

}

穷则github点星,达可兼济本人
显示 Gitment 评论
0%