IOS 控制器的数据传递 (顺传 and 逆传)

● 控制器之间的数据传递主要有2种情况:顺传和逆传

➢ 顺传

●  控制器的跳转方向: A ->C

●  数据的传递方向 : A -> C

● 数据的传递方式 : 在A的prepareForSegue:sender:方法中根据segue参数取得 destinationViewController,

   也就是控制器C, 直接给控制器C传递数据 (要在C的viewDidLoad方法中取得数据,来赋值给界面上的UI控件) 

顺传事例代码:

NJContatcsViewController.m(主控制器)

#import "NJContatcsViewController.h"
#import "NJAddViewController.h"
#import "NJContatc.h"
#import "NJEditViewController.h"

@interface NJContatcsViewController ()<UIActionSheetDelegate, NJAddViewControllerDelegate, NJEditViewControllerDelegate>
/**
 *  点击注销按钮
 */
- (IBAction)logout:(UIBarButtonItem *)sender;

/**
 *  保存所有用户数据
 */
@property (nonatomic, strong) NSMutableArray *contatcs;
@end

@implementation NJContatcsViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (IBAction)logout:(UIBarButtonItem *)sender
{
    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"确定要注销?" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"确定" otherButtonTitles:nil];
    [sheet showInView:self.view];
    
}
#pragma mark - UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (0 != buttonIndex) return;
    
    // 移除栈顶控制器
    [self.navigationController popViewControllerAnimated:YES];
}

// 无论是手动类型的segue还是自动类型的segue, 在跳转之前都会执行该方法
// 控制器跳转之前(执行segue之前)执行
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // 0.判断目标控制器是添加还是编辑
    // 1.取出目标控制器
    UIViewController *vc = segue.destinationViewController;
    if ([vc isKindOfClass:[NJAddViewController class]]) {
        NJAddViewController *addVc = (NJAddViewController *)vc;
        // 2.设置代理
        addVc.delegate = self;
    }else if ([vc isKindOfClass:[NJEditViewController class]]){
        // 传递数据
        NJEditViewController *editVc = (NJEditViewController *)vc;
        
        // 通过tableview获取被点击的行号
        NSIndexPath *path = [self.tableView indexPathForSelectedRow];
        // 取出被点击行的模型
        NJContatc *c = self.contatcs[path.row];
        NSLog(@"联系人列表 %p" , c);
        // 赋值模型
        editVc.contatc = c;
        // 设置代理
        editVc.delegate = self;
    }
}

#pragma mark - NJEditViewControllerDelegate
- (void)editViewControllerDidClickSavBtn:(NJEditViewController *)editViewController contatc:(NJContatc *)cpmtatc
{
    // 1.修改模型
//    NSIndexPath *path = [self.tableView indexPathForSelectedRow];
//    self.contatcs[path.row] = cpmtatc;
    
    // 2.刷新表格
    [self.tableView reloadData];
}

#pragma mark - NJAddViewControllerDelegate
- (void)addViewControllerDidAddBtn:(NJAddViewController *)editViewController contatc:(NJContatc *)contatc
{
    NSLog(@"添加了新联系人 %@ %@ %@", contatc.name, contatc.phoneNumber, contatc.email);
    // 1.保存数据到数组中
    [self.contatcs addObject:contatc];
    // 2.刷新表格
    [self.tableView reloadData];
}
- (NSMutableArray *)contatcs
{
    if (_contatcs == nil) {
        _contatcs = [NSMutableArray array];
    }
    return _contatcs;
}

#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.contatcs.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identifier = @"contatcs";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
//    if (cell == nil) {
//        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier];
//    }re
    
    // 设置数据
    NJContatc *c = self.contatcs[indexPath.row];//0
    NSLog(@"cellForRowAtIndexPath %p", c);
    cell.textLabel.text = c.name;
    cell.detailTextLabel.text = c.phoneNumber;
    // 返回cell
    return cell;
    
}
View Code

➢ 逆传 (使用代理方式)
● 控制器的跳转方向: A -> C

●  数据的传递方向 : C->A

●  数据的传递方式 : 让A成为C的代理, 在C中调用A的代理方法,通过代理方法的参数传递 数据给A 

逆传事例代码:

NJEditViewController.h(创建代理)

#import <UIKit/UIKit.h>
@class NJContatc, NJEditViewController;

@protocol NJEditViewControllerDelegate <NSObject>

- (void)editViewControllerDidClickSavBtn:(NJEditViewController *)editViewController contatc:(NJContatc *)cpmtatc;

@end

@interface NJEditViewController : UIViewController
/**
 *  用于接收联系人列表传递过来的数据
 */
@property (nonatomic, strong) NJContatc *contatc;

@property (nonatomic, weak) id<NJEditViewControllerDelegate> delegate;
@end
View Code

NJEditViewController.m(传递数据)

#import "NJEditViewController.h"
#import "NJContatc.h"

@interface NJEditViewController ()

@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *phoneField;
@property (weak, nonatomic) IBOutlet UIButton *saveBtn;
/**
 *  编辑按钮点击事件
 */
- (IBAction)editBtnOnClick:(UIBarButtonItem *)sender;
/**
 *  保存按钮点击事件
 *
 *  @param sender <#sender description#>
 */
- (IBAction)saveBtnOnClick:(UIButton *)sender;

@end

@implementation NJEditViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 设置姓名文本输入框
    self.nameField.text = _contatc.name;
    // 设置电话文本输入框
    self.phoneField.text = _contatc.phoneNumber;
    
    
    
    // 1.拿到通知中心
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    // 2.注册监听
    // 注意点: 一定要写上通知的发布者
    [center addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.nameField];
    [center addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.phoneField];

}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)textChange
{
    self.saveBtn.enabled = (self.nameField.text.length > 0  &&
                             self.phoneField.text.length > 0);
}

/*
 因为控制器的view是懒加载的, 用到的时候再加载
 而设置模型数据是在控制器跳转之前, 此时没有用到控制器的view,
 所以控制器的view还没有创建, 它的子控件也没有创建
 */
/*
- (void)setContatc:(NJContatc *)contatc
{
    _contatc = contatc;
    
    NSLog(@"%p - %p", self.nameField, self.phoneField);
    NSLog(@"%@ - %@", self.nameField, self.phoneField);
    // 设置姓名文本输入框
    self.nameField.text = _contatc.name;
    // 设置电话文本输入框
    self.phoneField.text = _contatc.phoneNumber;
}
 */
- (IBAction)editBtnOnClick:(UIBarButtonItem *)sender {
    
    
    if (self.nameField.enabled) {
         // 当前是编辑状态
        // 1.让文本输入框不可以交互
        self.nameField.enabled = NO;
        self.phoneField.enabled = NO;
        // 2.隐藏保存按钮
        self.saveBtn.hidden = YES;
        // 3.让键盘消失
//        [self.phoneField resignFirstResponder];
        [self.view endEditing:YES];
        // 4.修改按钮标题
        sender.title = @"编辑";
        // 5.还原数据
        // 设置姓名文本输入框
        self.nameField.text = _contatc.name;
        // 设置电话文本输入框
        self.phoneField.text = _contatc.phoneNumber;
        
    }else
    {
        // 当前是不可以编辑状态
        // 1.让文本输入框可以交互
        self.nameField.enabled = YES;
        self.phoneField.enabled = YES;
        // 2.显示保存按钮
        self.saveBtn.hidden = NO;
        // 3.让电话文本输入框召唤出键盘
        [self.phoneField becomeFirstResponder];
        // 4.修改按钮标题
        sender.title = @"取消";
    }
}

- (IBAction)saveBtnOnClick:(UIButton *)sender {
    
    // 1.移除栈顶控制器
    [self.navigationController popViewControllerAnimated:YES];
    
    // 2.修改模型数据
    NSLog(@"编辑界面 %p" , self.contatc);
    self.contatc.name = self.nameField.text;
    self.contatc.phoneNumber = self.phoneField.text;
    // 3.通知代理
    if ([self.delegate respondsToSelector:@selector(editViewControllerDidClickSavBtn:contatc:)]) {
        [self.delegate editViewControllerDidClickSavBtn:self contatc:self.contatc];
    }
    
}
View Code

NJContatcsViewController.m(主控制器 实现代理方法)

#pragma mark - NJEditViewControllerDelegate
- (void)editViewControllerDidClickSavBtn:(NJEditViewController *)editViewController contatc:(NJContatc *)cpmtatc
{
    // 1.修改模型
//    NSIndexPath *path = [self.tableView indexPathForSelectedRow];
//    self.contatcs[path.row] = cpmtatc;
    
    // 2.刷新表格
    [self.tableView reloadData];
}

#pragma mark - NJAddViewControllerDelegate
- (void)addViewControllerDidAddBtn:(NJAddViewController *)editViewController contatc:(NJContatc *)contatc
{
    NSLog(@"添加了新联系人 %@ %@ %@", contatc.name, contatc.phoneNumber, contatc.email);
    // 1.保存数据到数组中
    [self.contatcs addObject:contatc];
    // 2.刷新表格
    [self.tableView reloadData];
}
- (NSMutableArray *)contatcs
{
    if (_contatcs == nil) {
        _contatcs = [NSMutableArray array];
    }
    return _contatcs;
}
View Code
原文地址:https://www.cnblogs.com/liuwj/p/6530854.html