UI中的界面之间的值传递 <二>

 从后往前传 —— 代理传值

代理传值 (代理是前一个界面, 协议在后一个界面写, 后一个界面是委托方, 前一个界面是被委托方.)

    一 : 在后一个界面定义协议 (定义一个用于传值的方法, 而且方法必须要有参数, 参数类型要与所传数据的类型保持一致)

    二 : 在后一个界面定义代理属性, 用来保存代理对象.

    三 : 设置后一个界面的代理 -- 在前一个界面进入后一个界面之前, 设置前一个界面为后一个界面的代理.

    四 : 前一个界面服从协议.

    五 : 前一个界面实现协议中的方法.

    六 : 后一个界面让代理执行协议中的方法 (执行方法时, 把传输的数据作为方法的参数进行传递), 时机 : 返回上一界面之前.

例如有两个视图控制器:

FirstViewController 和 SecondViewController

在这两个视图控制器中设置一个textField 和 label, 并且把SecondViewController的view上的textField上输入的text显示到FirstViewController的label上.

SecondViewController.h文件中

#import <UIKit/UIKit.h>

 // 代理传值 第一步 : 定义协议

@protocol SecondViewControllerDelegate <NSObject>

- (void)passValue:(NSString *)data;

@end

@interface SecondViewController : UIViewController

 // 代理传值第二步 : 定义代理属性, 存储代理对象

@property (nonatomic, assign) id<SecondViewControllerDelegate> delegate;

@end

FirstViewController.m文件中

#import "FirstViewController.h"

#import "SecondViewController.h"

// 代理传值第四步 : 服从协议.

@interface FirstViewController () <SecondViewControllerDelegate>

@end

@implementation FirstViewController

#pragma mark -- second view controller delegate

// 代理传值第五步 : 前一个界面实现协议中的方法

- (void)passValue:(NSString *)data {

    

    ((UILabel *)[self.view viewWithTag:200]).text = data;

    

}

- (void)viewDidLoad {

    [super viewDidLoad];

      /**

     导航控制器的工作原理: 

        导航控制器以栈的形式管理视图控制器, 当进入下一个界面时, 该视图控制器入栈, 当返回上一界面时, 该视图控制器出栈, 入栈前, 视图控制器开辟空间, 出栈后, 视图控制器被系统回收, 屏幕永远显示的是导航控制器的栈顶元素.

     */    

    // 进入下一界面的按钮

    [self setupButton];

// 设置TextField

    [self setupTextField];

// 设置Label

    [self setupLabel];

}

// 创建button

- (void)setupButton {

    UIButton *pushBtn = [UIButton buttonWithType:UIButtonTypeSystem];

    pushBtn.frame = CGRectMake(20, 100, 280, 40);

    [pushBtn setTitle:@"进入下一个界面" forState:UIControlStateNormal];

    pushBtn.backgroundColor = [UIColor blueColor];

    [pushBtn addTarget:self action:@selector(handlePushBtn:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:pushBtn];

}

 // 创建textField

- (void)setupTextField {

    UITextField *textFiled = [[UITextField alloc] initWithFrame:CGRectMake(20, 230, 280, 40)];

    textFiled.placeholder = @"显示到第二个界面上";

    [self.view addSubview:textFiled];

    textFiled.tag = 100;

    textFiled.backgroundColor = [UIColor grayColor];

    [textFiled release];

}

// 创建label

- (void)setupLabel {

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 300, 280, 40)];

    label.backgroundColor = [UIColor whiteColor];

    label.layer.borderWidth = 2;

    label.layer.cornerRadius = 5;

    label.tag = 200;

    [self.view addSubview:label];

    [label release];

#pragma mark -- button action

- (void)handlePushBtn:(UIButton *)sender {

// 代理传值, 从后往前传

   // 1. 创建的二个视图控制器

    SecondViewController *secondVC = [[SecondViewController alloc] init];

    // 代理传值 第三步 :给后一个界面指定代理对象

    secondVC.delegate = self;

    // 2. 通过导航控制push到下一个界面(视图控制器自带的navigationController 属性能够获取到管理当前视图控制器的导航控制器, 然后, 再通过导航控制器进行push)

    [self.navigationController pushViewController:secondVC animated:YES]; // 该行代码表示进入下一个界面. 

    // 3. 释放

    [secondVC release];

    }

@end

SecondViewController.m 文件中

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {

    [super viewDidLoad];

// 设置下一页面的按钮

    [self setupPushButton];

// 设置TextField

    [self setupTextField];

// 设置Label

    [self setupLabel];

// 设置上一页面的按钮

    [self setupPopButton];

}

// 创建button

- (void)setupButton {

    UIButton *pushBtn = [UIButton buttonWithType:UIButtonTypeSystem];

    pushBtn.frame = CGRectMake(20, 100, 280, 40);

    [pushBtn setTitle:@"进入下一个界面" forState:UIControlStateNormal];

    pushBtn.backgroundColor = [UIColor blueColor];

    [pushBtn addTarget:self action:@selector(handlePushBtn:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:pushBtn];

}

 // 创建textField

- (void)setupTextField {

    UITextField *textFiled = [[UITextField alloc] initWithFrame:CGRectMake(20, 230, 280, 40)];

    textFiled.placeholder = @"显示到第二个界面上";

    [self.view addSubview:textFiled];

    textFiled.tag = 100;

    textFiled.backgroundColor = [UIColor grayColor];

    [textFiled release];

}

// 创建label

- (void)setupLabel {

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 300, 280, 40)];

    label.backgroundColor = [UIColor whiteColor];

    label.layer.borderWidth = 2;

    label.layer.cornerRadius = 5;

    label.tag = 200;

    [self.view addSubview:label];

    [label release];

#pragma mark -- button action

- (void)handlePopBtn:(UIButton *)sender {

   

    // 代理传值第六步 : 让代理执行任务

    // 安全处理, 判断代理是否实现了方法, 防止崩溃

    if ([self.delegate respondsToSelector:@selector(passValue:)]) {

        [self.delegate passValue:[(UITextField *)[self.view viewWithTag:200] text]];

    }

    // 1. 返回上一界面

    [self.navigationController popViewControllerAnimated:YES];

}

- (void)dealloc {

    [_data release];

    [super dealloc];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end

原文地址:https://www.cnblogs.com/hanpengshuai/p/4764611.html