object-c – 在视图控制器之间传递数据

我是iOS和Objective-C以及整个MVC范例的新手,我坚持以下内容:

我有一个视图作为数据输入表单,我想让用户选择多个产品。产品列在另一个带有a的视图中,UITableViewController并且我启用了多个选择。

我的问题是,如何将数据从一个视图传输到另一个视图?我将UITableView在数组中保存选择,但是如何将其传递回上一个数据输入表单视图,以便在提交表单时将其与其他数据一起保存到Core Data?

我已经四处浏览并看到一些人在app delegate中声明了一个数组。我读了一些关于单身人士的内容,但不明白这些是什么,我读了一些关于创建数据模型的内容。

执行此操作的正确方法是什么?我将如何进行此操作?


这个问题似乎在stackoverflow上非常流行,所以我想我会尝试给出一个更好的答案来帮助像iOS这样的iOS世界开始的人们。

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

传递数据

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

对于这个例子,我们将拥有ViewControllerAViewControllerB

要传递BOOLViewControllerAViewControllerB我们将执行以下操作。

  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];

    这将设置isSomethingEnabledViewControllerBBOOL价值YES

使用Segues传递数据

如果您使用的是Storyboard,则最有可能使用segues,并且需要此过程来传递数据。这与上面的类似,但不是在推送视图控制器之前传递数据,而是使用一个名为的方法

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

所以要传递一个BOOLfrom ViewControllerAViewControllerB我们会做以下事情:

  1. 在为… ViewControllerB.h创建属性BOOL
    @property (nonatomic, assign) BOOL isSomethingEnabled;
  2. ViewControllerA你需要告诉它ViewControllerB所以使用一个
    #import "ViewControllerB.h"
  3. 从创建的SEGUE ViewControllerAViewControllerB的故事板,并给它一个标识符,在这个例子中,我们叫它"showDetailSegue"
  4. 接下来我们需要将方法添加到ViewControllerA执行任何segue时调用的方法,因此我们需要检测调用哪个segue然后执行某些操作。在我们的示例中,我们将检查"showDetailSegue"是否已执行,我们将传递BOOLViewControllerB
    -(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;
        }
    }

    这将设置isSomethingEnabledViewControllerBBOOL价值YES

传递数据

要将数据传回ViewControllerBViewControllerA您需要使用Protocols and DelegatesBlocks,后者可以用作回调的松散耦合机制。

为此,我们将成为ViewControllerA代表ViewControllerB。这允许ViewControllerB发回消息以ViewControllerA使我们能够发回数据。

对于ViewControllerA将要代表ViewControllerB它必须符合ViewControllerB的协议,我们必须指定。这告诉ViewControllerA它必须实现哪些方法。

  1. ViewControllerB.h,低于#import,但在上面@interface指定协议。
    @class ViewControllerB;
    
    @protocol ViewControllerBDelegate <NSObject>
    - (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 <ViewControllerBDelegate>
  5. ViewControllerA.m我们的协议中实现以下方法
    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
    {
        NSLog(@"This was returned from ViewControllerB %@",item);
    }
  6. 在推viewControllerB送到导航堆栈之前,我们需要告诉 ViewControllerBViewControllerA是它的委托,否则我们会收到错误。
    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
    viewControllerB.delegate = self
    [[self navigationController] pushViewController:viewControllerB animated:YES];

参考

添加评论

友情链接:蝴蝶教程