控制器之间的数据传递——storyboard中控制器的数据传递

来源:互联网 发布:青岛少儿编程培训班 编辑:程序博客网 时间:2024/06/16 00:11

在APP开发中,我们经常需要在不同的控制器之间进行数据传递,按照传递的方向,可分为顺传和逆传;按照是否通过第三者(如通过单例、或者文件等)传递数据,可以分为:直接传递和间接传递;一般的还把控制器之间的数据传递分为:属性传值、代理传值、Block传值、全局变量传值、文件传值(NSUserDefaults传值,或者通过其它数据持久化方式传值)、单例传值(UIApplication传值,通知传值,或自定义一个单例)
本篇博文主要讲解在storyboard中,控制器之间通过属性传递数据,后续会把其他传值方式写完

Storyboard中控制器的数据传递

一. 重点

接收数据的一方要有接收数据的属性,如果是逆传数据,要提前拿到接收数据的视图控制器

二. 知识点

  1. Segue:Storyboard上每一根用来界面跳转的联线,都是一个UIStoryboardSegue对象(简称Segue)

  2. Segue分为自动型和手动型,自动型一般用于不关心数据传递的,想直接通过按钮跳转到另外一个视图控制器的操作;手动型一般用于需要数据传递的操作,且Segue需要设置一个标识

  3. identifier:只能通过storyboard设置,使用代码设置identifier没有意义,因为使用storyboard才有Segue

  4. 只有来源控制器才能执行performSegueWithIdentifier:sender:方法

三. 关于UIStoryboardSegue对象的底层执行

  1. 根据identifier去storyboard中找到对应的联线,新建UIStoryboardSegue对象,再设置UIStoryboardSegue对象的sourceViewController(来源控制器)和设置destinationViewController(目标控制器)

  2. 调用sourceViewController的performSegueWithIdentifier:sender:方法,做一些跳转前的准备工作并且传入创建好的Segue对象

  3. 调用Segue对象的performSegueWithIdentifier:sender:方法开始执行界面跳转操作,如果segue的style是push,取得sourceViewController所在的UINavigationController,调用UINavigationController的push方法将destinationViewController压入栈中,完成跳转;如果segue的style是modal,调用sourceViewController的presentViewController方法将destinationViewController展示出来

四. 具体步骤实现

1. 在storyboard中,拖入控制器

在storyboard中,把默认的视图控制器删除,并拖入一个导航控制器UINavigationController和两个视图控制器UIViewController,再把导航控制器默认的根控制器删除,最后对拖进来的两个视图控制器布局子控件

这里写图片描述

2. 设置导航控制器的根控制器

按住Ctrl键,从导航控制器拖线到视图控制器,并在选项框中选择“root view controller”

这里写图片描述

3. 设置导航控制器为程序启动默认加载的控制器

这里写图片描述

4. 拖线设置视图控制器之间的切换

按住Ctrl键,从视图控制器拖线到要跳转到的视图控制器,并在选项框中选择push
注意:是从视图控制器拖线到要跳转的视图控制器,而不是从按钮拖线到视图控制器

这里写图片描述

这里写图片描述

5. 设置storyboard中segue对象的标识符ID

这里写图片描述

6. 设置视图控制器的所属类

创建一个UIViewController的子类TwoViewController,然后把工程默认生成的ViewController和刚创建的TwoViewController设置为storyboard里拖入的两个视图控制器的所属类

这里写图片描述


这里写图片描述

7. 编写数据传递相关代码

(1). ViewController类

---------- ViewController.h文件#import <UIKit/UIKit.h>@interface ViewController : UIViewController// 接收界面2的数据@property (nonatomic,strong) NSString *oneStr;@end---------- ViewController.m文件#import "ViewController.h"#import "TwoViewController.h"@interface ViewController ()// 显示界面2传来的数据@property (weak, nonatomic) IBOutlet UILabel *oneLabel;// 收集数据@property (weak, nonatomic) IBOutlet UITextField *oneTextField;@end@implementation ViewController// 在视图即将显示时,把接受到的值赋值给子控件// 注意:不能在逆序传值的时候直接给子控制赋值,因为传值的时候要接收值的视图还没有加载,不能接收值- (void)viewWillAppear:(BOOL)animated {  // 把届面2传回的值给oneLabel  self.oneLabel.text = self.oneStr;}// 通过UIStoryboardSegue对象切换视图,会调用此方法- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{  // 获取目的控制器  TwoViewController *vc= segue.destinationViewController;  // 给目的控制器赋值,即把界面1的文本框的数据给界面2  vc.nameStr = self.oneTextField.text;  // 把界面1的控制器给届面2,用于数据的逆序传递  vc.oneVC = self;}// 跳转方法- (IBAction)jump:(id)sender {  // 设置Segue对象的标识符,注意要与storyboard中所设置的标识符相同  NSString *segueIdentifie = @"oneToTwo";  // 会通过标识符加载storyboard里面的Segue对象  [self performSegueWithIdentifier:segueIdentifie sender:nil];}@end

(2). TwoViewController类

---------- TwoViewController.h文件#import <UIKit/UIKit.h>#import "ViewController.h"@interface TwoViewController : UIViewController// 接收界面1的数据@property (nonatomic,strong) NSString *nameStr;// 保存界面1的控制器@property (nonatomic,strong) ViewController *oneVC;@end---------- TwoViewController.m文件#import "TwoViewController.h"#import "ViewController.h"@interface TwoViewController ()// 显示界面一传来的数据@property (weak, nonatomic) IBOutlet UILabel *twoLabel;// 收集数据@property (weak, nonatomic) IBOutlet UITextField *twoTextfield;@end@implementation TwoViewController// 跳转方法- (IBAction)twoToOne:(id)sender {  // 1.把数据传到界面1  self.oneVC.oneStr = self.twoTextfield.text;  // 2.跳转到界面1  [self.navigationController popViewControllerAnimated:YES];}- (void)viewDidLoad {    [super viewDidLoad];  // 把界面1传来的数据给twoLabel  self.twoLabel.text = _nameStr;}@end
0 0