iOS开发之控制器之间传值

佐手、 提交于 2020-02-29 13:21:30

    多个界面之间的跳转,免不了要进行数据传递,可以是顺向的,也可以是逆向的。android中activity之间数据传递是用startActivity(Intent)和startActivityForResult方式,逆向的时候在源activity中重写onActivityResult方法,在这个方法中获取传递过来的数据。iOS中可以利用UIStoryboardSegue顺向或者用代理、block逆向进行值传递。

一、Segue方式:

    首先要知道Segue是什么,storyboard上每一条用来描述界面跳转的线,就是一个UIStoryboardSegue对象,简称Sugue。它有三个属性:

@property (nullable, nonatomic, copy, readonly) NSString *identifier;//segue的唯一标识
@property (nonatomic, readonly) __kindof UIViewController *sourceViewController;//源控制器
@property (nonatomic, readonly) __kindof UIViewController *destinationViewController;//目标控制器

根据Segue执行跳转的时刻,可以将其分为两种类型,自动和手动。自动类型是点击某个控件后,自动执行Segue完成界面跳转。手动类型是需要通过写代码来完成跳转。如果是手动类型,就需要给Segue设置一个identifier,并且在源控制器中执行这么一个方法:

[self performSegueWithIdentifier:@"identifier" sender:nil];

它内部的执行过程是这样的,创建segue->设置源控制器(segue.sourceViewController = self)->创建目的控制器,segue.destinationViewController = 目的控制器->[self prepareForSegue]跳转之前的准备操作->[segue perform]->判断下segue的类型,如果是push,拿到导航控制器push,[self.navigationController pushViewController:segue.destinationViewController animated:YES];

也就是说,在prepareForSegue方法中可以拿到目的控制器,自然就可以将数据传递到目的控制器了。这是顺向传递。

逆向传递需要用代理的方式,A、B两个控制器,B在栈顶,现在B出栈要将数据传递给A,首先要在A跳转到B时让A成为B的代理,遵守代理协议,B在需要传数据的地方通知代理来处理时间并将数据扔给代理,意思就是B对A说这事我就交给你来做了,你要的东西我给你,你去做。这时候A实现代理协议中的方法,就拿到了B传过来的数据。

A控制器:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    //A拿到B控制器,成为B的代理
    BViewController *BVC = segue.destinationViewController;
    BVC.delegate = self;
    
}

B控制器:

    //在处理返回逻辑的方法中
    
    //准备好要传递的数据
    
    //通知代理
    if ([_delegate respondsToSelector:@selector(代理方法)]) {
        [_delegate 代理方法(将数据当做参数)];
    }
    
    //返回到A控制器
    [self.navigationController popViewControllerAnimated:YES];

最后在A控制器中实现代理方法,就能获取到B传递的数据了。


二、block方式:

现在B控制器中定义一个block属性

typedef 返回类型(^block别名)(参数);

//别名一般是类名+Block
@property(nonatomic, strong) block别名 block;

在A控制器中执行跳转的时候我们拿到了B控制器,在B控制器的block属性中将要执行的操作代码先保存起来

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    
    BController *BVC = segue.destinationViewController;
    
    BVC.block = ^(参数){
        //TODO:将来要进行的操作
        //实际上这里的参数就是block传递过来的数据,我们拿到这个参数就可以进行我们想要做的事情了。逆向传参就完成了
    };
    
}

当返回上一个控制器之前,要让block帮我们完成某些事情

if (_block) {
    _block(传递的数据);
}


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!