iOS开发之界面通信(界面传值)浅谈

作者: SJPOP | 来源:发表于2016-02-20 23:51 被阅读416次

    本文简单介绍几种界面通信的方式,给出相应的示例。

    1. 属性传值

    属性传值是最简单的一种传值方式,通常用于从前向后传值,即在第二个视图控制器获得第一个视图控制器的部分信息。

    示例:创建两个UIViewController,在第一个页面的UITextField里输入文字,跳转到第二个页面之后,在第二个页面的UILabel上显示出来。

    属性传值示例

    第一个页面:

    FirstViewController.m文件:

    #import "FirstViewController.h"
    #import "SecondViewController.h"
    
    @interface FirstViewController ()
    @property (nonatomic, strong) UITextField *firstTextField;
    @end
    
    @implementation FirstViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor cyanColor];
        self.navigationItem.title = @"第一页";
        self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"下一页" style:UIBarButtonItemStyleDone target:self action:@selector(nextVC:)];
        
        self.firstTextField = [[UITextField alloc] initWithFrame:CGRectMake(100, 200, 214, 40)];
        _firstTextField.backgroundColor = [UIColor whiteColor];
        _firstTextField.placeholder = @"输入要传入下一页面的值";
        [self.view addSubview:_firstTextField];
        
    }
    

    在触发的点击事件中 将第一个页面的输入框中输入的信息赋值给第二个页面的label,然后跳转到第二个页面:

    -(void)nextVC:(UIBarButtonItem *)sender{
        SecondViewController *secondVC = [[SecondViewController alloc] init];
        secondVC.stringFromFirstVC = _firstTextField.text;
        [self.navigationController pushViewController:secondVC animated:YES];
    }
    
    @end
    

    第二个页面:

    SecondViewController.h文件:

    暴露一个属性,用于传值。

    #import <UIKit/UIKit.h>
    
    @interface SecondViewController : UIViewController
    @property (nonatomic, strong) NSString *stringFromFirstVC;
    @end
    

    SecondViewController.m文件:

    #import "SecondViewController.h"
    
    @interface SecondViewController ()
    
    @end
    
    @implementation SecondViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.navigationItem.title = @"第二页";
        self.view.backgroundColor = [UIColor lightGrayColor];
        
        self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStyleDone target:self action:@selector(back:)];
    
        UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(100, 200, 214, 40)];
        label.text = self.stringFromFirstVC;
        [self.view addSubview:label];
    }
    
    -(void)back:(UIBarButtonItem *)sender{
        [self.navigationController popViewControllerAnimated:YES];
    }
    
    @end
    

    2. 代理传值

    定义一个用来传值的协议,设置代理去执行传值。
    示例:创建两个UIViewController,在第二个页面的UITextField里输入文字,跳转回第一个页面之后,在第一个页面的UILabel上显示出来。

    从第一页进入第二页 在第二个页面输入文字,跳转回第一个页面

    第一个页面:

    FirstViewController.m文件:

    #import "FirstViewController.h"
    #import "SecondViewController.h"
    
    @interface FirstViewController ()<PassValueDelegate>   //遵守协议
    @property (nonatomic, strong) UILabel *label;
    @end
    
    @implementation FirstViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor cyanColor];
        self.navigationItem.title = @"第一页";
        
        self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"下一页" style:UIBarButtonItemStyleDone target:self action:@selector(nextVC:)];
        self.label = [[UILabel alloc] initWithFrame:CGRectMake(100, 300, 214, 40)];
        _label.backgroundColor = [UIColor yellowColor];
        [self.view addSubview:_label];
    }
    

    触发的点击事件:设置代理后跳转到第二个页面:

    -(void)nextVC:(UIBarButtonItem *)sender{
        SecondViewController *secondVC = [[SecondViewController alloc] init];
        //将第一个页面指定为第二个页面的代理!
        secondVC.delegate = self;
        [self.navigationController pushViewController:secondVC animated:YES];
    }
    

    实现代理方法:

    -(void)passValue:(NSString *)value{
        _label.text = value;
    }
    
    @end
    

    第二个页面:

    SecondViewController.h文件:

    定义一个用来传值的协议,声明代理属性

    #import <UIKit/UIKit.h>
    
    @protocol PassValueDelegate <NSObject>
    
    -(void)passValue:(NSString *)value;
    
    @end
    
    @interface SecondViewController : UIViewController
    
    //声明代理属性,其中<PassValueDelegate>指定其遵守的协议
    @property(nonatomic,assign)id<PassValueDelegate>delegate;
    
    @end
    

    SecondViewController.m文件:

    #import "SecondViewController.h"
    
    @interface SecondViewController ()
    @property (nonatomic, strong) UITextField *textField;
    @end
    
    @implementation SecondViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.navigationItem.title = @"第二页";
        self.view.backgroundColor = [UIColor lightGrayColor];
        self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStyleDone target:self action:@selector(back:)];
    
        self.textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 300, 214, 40)];
        _textField.backgroundColor = [UIColor whiteColor];
        _textField.placeholder = @"输入要传入上一页面的值";
        [self.view addSubview:_textField];
        
    }
    
    -(void)back:(UIBarButtonItem *)sender{
        //代理去执行传值!!!
        [_delegate passValue:_textField.text];
        //跳转回第一页
        [self.navigationController popViewControllerAnimated:YES];
    }
    

    3. block传值

    使用block实现回调功能的优点是比较清晰,简化代码。
    注意:在block实现部分,不要直接使用self、实例变量、属性,因为会造成循环引用。
    示例:创建两个UIViewController,在第二个页面的UITextField里输入文字,跳转回第一个页面之后,在第一个页面的UILabel上显示出来。

    从第一页进入第二页 在第二个页面输入文字,跳转回第一个页面

    第一个页面:

    FirstViewController.m文件:

    #import "FirstViewController.h"
    #import "SecondViewController.h"
    
    @interface FirstViewController ()
    @property(nonatomic,strong)UILabel *label;
    @end
    
    @implementation FirstViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor =[UIColor blueColor];
        self.label = [[UILabel alloc] initWithFrame:CGRectMake(100, 300, 214, 50)];
        _label.backgroundColor = [UIColor whiteColor];
        [self.view addSubview:_label];
    }
    

    添加触摸事件,模态出下一个视图(用别的方式也可以)

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        SecondViewController *secondVC = [[SecondViewController alloc] init];
        //block的实现
        __weak FirstViewController *temp = self;
        secondVC.block = ^(NSString *string){
            //通过回调将传进来的字符串赋值给_label
            temp.label.text = string;
        };
        //跳转到第二个页面
        [self presentViewController:secondVC animated:YES completion:nil];
    }
    
    @end
    

    第二个页面:

    SecondViewController.h文件:

    在这里定义一个block,声明block属性。
    ARC中block的语义设置使用strong即可,MRC中block的语义设置是copy(把block从栈区拷贝到堆区,使用完之后,在dealloc中释放)。

    #import <UIKit/UIKit.h>
    //定义有参无返回值的匿名函数(传递字符串)
    typedef void (^PassValueBlock)(NSString *);
    
    @interface SecondViewController : UIViewController
    @property (nonatomic, strong) PassValueBlock block;
    @end
    

    SecondViewController.m文件:

    #import "SecondViewController.h"
    
    @interface SecondViewController ()
    @property (nonatomic, strong) UITextField *textField;
    @end
    
    @implementation SecondViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor greenColor];
        self.textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 300, 214, 50)];
        _textField.placeholder = @"block传值";
        _textField.backgroundColor = [UIColor orangeColor];
        [self.view addSubview:_textField];
    }
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        //调用block
        self.block(_textField.text);   
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    @end
    

    相关文章

      网友评论

        本文标题:iOS开发之界面通信(界面传值)浅谈

        本文链接:https://www.haomeiwen.com/subject/okbvkttx.html