栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在视图控制器之间传递数据

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在视图控制器之间传递数据

这个问题在stackoverflow上似乎很受欢迎,所以我想我会尝试给出一个更好的答案来帮助像我这样的iOS初学者。

我希望这个答案足够清晰,让人们理解,并且我没有错过任何东西。

转发数据

将数据从另一个视图控制器传递到视图控制器。如果要将对象/值从一个视图控制器传递到可能要推送到导航堆栈的另一个视图控制器,则可以使用此方法。

在这个例子中,我们将

ViewControllerA
和
ViewControllerB

要将

BOOL
值从传递
ViewControllerA
给
ViewControllerB
我们,请执行以下操作。

  1. 在

    ViewControllerB.h
    为
    BOOL

    @property (nonatomic, assign) BOOL isSomethingEnabled;
  2. 在

    ViewControllerA
    你需要告诉它,
    ViewControllerB
    所以使用

    #import "ViewControllerB.h"

然后在您想加载视图的位置。

didSelectRowAtIndex
或一些
IBAction
您需要设置的属性,
ViewControllerB
然后再将其推入导航堆栈。

    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];viewControllerB.isSomethingEnabled = YES;[self pushViewController:viewControllerB animated:YES];

这将设置

isSomethingEnabled
在
ViewControllerB
以
BOOL
价值
YES
。

使用Segues转发数据

如果使用情节提要,则很有可能使用segues,并且需要此过程将数据转发。这与上面的类似,但是不是在推送视图控制器之前传递数据,而是使用一种称为

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

因此,要将

BOOL
from 传递
ViewControllerA
给
ViewControllerB
我们,请执行以下操作:

  1. 在

    ViewControllerB.h
    为
    BOOL

    @property (nonatomic, assign) BOOL isSomethingEnabled;
  2. 在

    ViewControllerA
    你需要告诉它,
    ViewControllerB
    所以使用

    #import "ViewControllerB.h"
  3. 从创建的SEGUE

    ViewControllerA
    到
    ViewControllerB
    的故事板,并给它一个标识符,在这个例子中,我们叫它
    "showDetailSegue"

  4. 接下来,我们需要在

    ViewControllerA
    执行任何segue时将方法添加到被调用的方法,因此,我们需要检测调用了哪个segue并执行某些操作。在我们的示例中,我们将检查
    "showDetailSegue"
    是否执行了此操作,然后将我们的
    BOOL
    值传递给
    ViewControllerB

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{if([segue.identifier isEqualToString:@"showDetailSegue"]){    ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;    controller.isSomethingEnabled = YES;}

    }

如果您将视图嵌入导航控制器中,则需要将上面的方法稍微更改为以下方法

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{    if([segue.identifier isEqualToString:@"showDetailSegue"]){        UINavigationController *navController = (UINavigationController *)segue.destinationViewController;        ViewControllerB *controller = (ViewControllerB *)navController.topViewController;        controller.isSomethingEnabled = YES;    }}

这将设置

isSomethingEnabled
在
ViewControllerB
以
BOOL
价值
YES
。

传回数据

要将数据传递回

ViewControllerB
给
ViewControllerA
您,您需要使用 Protocols and Delegates 或
Blocks ,后者可以用作回调的松散耦合机制。

为此,我们将

ViewControllerA
委托
ViewControllerB
。这样可以
ViewControllerB
将信息发送回去,
ViewControllerA
使我们能够将数据发送回去。

对于

ViewControllerA
成为一个代表
ViewControllerB
它必须符合
ViewControllerB
我们有指定的协议。这告诉
ViewControllerA
它必须实现哪些方法。

  1. 在

    ViewControllerB.h
    中的
    #import
    ,但在上方
    @interface
    指定协议。

    @class ViewControllerB;

    @protocol ViewControllerBDelegate
    - (void)addItemViewController:(ViewControllerB )controller didFinishEnteringItem:(NSString )item;
    @end

  2. 接下来仍然

    ViewControllerB.h
    需要设置
    delegate
    属性并在
    ViewControllerB.m

    @property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
  3. 在

    ViewControllerB
    我们
    delegate
    弹出视图控制器时,我们会调用一条消息。

    NSString *itemToPassBack = @"Pass this value back to ViewControllerA";

    [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];

  4. 就是这样

    ViewControllerB
    。现在,中
    ViewControllerA.h
    ,告诉
    ViewControllerA
    导入
    ViewControllerB
    并遵守其协议。

    #import "ViewControllerB.h"

    @interface ViewControllerA : UIViewController

  5. 在

    ViewControllerA.m
    落实从我们的协议下面的方法

    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item

    {
    NSLog(@”This was returned from ViewControllerB %@”,item);
    }

  6. 在推

    viewControllerB
    送到导航堆栈之前,我们需要告诉
    ViewControllerB
    它
    ViewControllerA
    是它的委托,否则我们将得到一个错误。

    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];

    viewControllerB.delegate = self
    [[self navigationController] pushViewController:viewControllerB animated:YES];


参考资料

  1. 《 View Controller编程指南》 中的使用委派与其他View Controller通信 __
  2. 代表图案

NSNotification中心 这是传递数据的另一种方法。

// add observer in controller(s) where you want to receive data[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeeplinking:) name:@"handleDeeplinking" object:nil];-(void) handleDeeplinking:(NSNotification *) notification {    id someObject = notification.object // some custom object that was passed with notification fire.}// post notificationid someObject;[NSNotificationCenter.defaultCenter postNotificationName:@"handleDeeplinking" object:someObject];

将数据从一个类传递回另一个类 (一个类可以是任何控制器,网络/会话管理器,UIView子类或任何其他类)

块是匿名函数。

本示例将数据从 控制器B 传递到 控制器A

定义一个块

@property void(^selectedVoucherBlock)(NSString *); // in ContollerA.h

*在需要值的地方 *添加块处理程序(侦听器) (例如,您需要在ControllerA中的API响应或在A上需要ContorllerB数据)

// in ContollerA.m- (void)viewDidLoad {    [super viewDidLoad];    __unsafe_unretained typeof(self) weakSelf = self;    self.selectedVoucherBlock = ^(NSString *voucher) {        weakSelf->someLabel.text = voucher;    };}

转到控制器B

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];ControllerB *vc = [storyboard instantiateViewControllerWithIdentifier:@"ControllerB"];vc.sourceVC = self;    [self.navigationController pushViewController:vc animated:NO];

火块

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {    NSString *voucher = vouchersArray[indexPath.row];    if (sourceVC.selectVoucherBlock) {        sourceVC.selectVoucherBlock(voucher);    }    [self.navigationController popToViewController:sourceVC animated:YES];}

块的另一个工作示例



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/636296.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号