Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
535 views
in Technique[技术] by (71.8m points)

ios - 在视图控制器之间传递数据(Passing Data between View Controllers)

I'm new to iOS and Objective-C and the whole MVC paradigm and I'm stuck with the following:

(我是iOS和Objective-C以及整个MVC范例的新手,但我坚持以下几点:)

I have a view that acts as a data entry form and I want to give the user the option to select multiple products.

(我有一个充当数据输入表单的视图,我想给用户选择多个产品的选项。)

The products are listed on another view with a UITableViewController and I have enabled multiple selections.

(这些产品在另一个带有UITableViewController视图中列出,并且我启用了多个选择。)

My question is, how do I transfer the data from one view to another?

(我的问题是,如何将数据从一个视图传输到另一个视图?)

I will be holding the selections on the UITableView in an array, but how do I then pass that back to the previous data entry form view so it can be saved along with the other data to Core Data on submission of the form?

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

I have surfed around and seen some people declare an array in the app delegate.

(我到处逛逛,看到有人在应用程序委托中声明了一个数组。)

I read something about Singletons but don't understand what these are and I read something about creating a data model.

(我读了一些有关Singletons的内容,但不了解它们是什么,并且读了一些有关创建数据模型的知识。)

What would be the correct way of performing this and how would I go about it?

(什么是执行此操作的正确方法,我将如何处理?)

  ask by Matt Price translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This question seems to be very popular here on stackoverflow so I thought I would try and give a better answer to help out people starting in the world of iOS like me.

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

I hope this answer is clear enough for people to understand and that I have not missed anything.

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

Passing Data Forward

(转发数据)

Passing data forward to a view controller from another view controller.

(将数据从另一个视图控制器传递到视图控制器。)

You would use this method if you wanted to pass an object/value from one view controller to another view controller that you may be pushing on to a navigation stack.

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

For this example, we will have ViewControllerA and ViewControllerB

(对于此示例,我们将有ViewControllerAViewControllerB)

To pass a BOOL value from ViewControllerA to ViewControllerB we would do the following.

(要将BOOL值从ViewControllerA传递到ViewControllerB我们需要执行以下操作。)

  1. in ViewControllerB.h create a property for the BOOL

    (在ViewControllerB.hBOOL创建一个属性)

     @property (nonatomic, assign) BOOL isSomethingEnabled; 
  2. in ViewControllerA you need to tell it about ViewControllerB so use an

    (在ViewControllerA您需要向其介绍ViewControllerB因此请使用)

     #import "ViewControllerB.h" 

    Then where you want to load the view eg.

    (然后在你想加载视图的地方。)

    didSelectRowAtIndex or some IBAction you need to set the property in ViewControllerB before you push it onto nav stack.

    (didSelectRowAtIndex或某些IBAction ,需要先在ViewControllerB设置该属性,然后再将其推入导航堆栈。)

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

    This will set isSomethingEnabled in ViewControllerB to BOOL value YES .

    (这会将ViewControllerB isSomethingEnabled设置为BOOLYES 。)

Passing Data Forward using Segues

(使用Segues转发数据)

If you are using Storyboards you are most likely using segues and will need this procedure to pass data forward.

(如果使用情节提要,则很有可能使用segues,并且需要此过程将数据转发。)

This is similar to the above but instead of passing the data before you push the view controller, you use a method called

(这与上面的类似,但是不是在推送视图控制器之前传递数据,而是使用一种称为)

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

So to pass a BOOL from ViewControllerA to ViewControllerB we would do the following:

(因此,要将BOOLViewControllerA传递到ViewControllerB我们需要执行以下操作:)

  1. in ViewControllerB.h create a property for the BOOL

    (在ViewControllerB.hBOOL创建一个属性)

     @property (nonatomic, assign) BOOL isSomethingEnabled; 
  2. in ViewControllerA you need to tell it about ViewControllerB so use an

    (在ViewControllerA您需要向其介绍ViewControllerB因此请使用)

     #import "ViewControllerB.h" 
  3. Create a the segue from ViewControllerA to ViewControllerB on the storyboard and give it an identifier, in this example we'll call it "showDetailSegue"

    (在情节ViewControllerB上从ViewControllerAViewControllerB创建一个序列,并为其指定一个标识符,在本示例中,我们将其称为"showDetailSegue")

  4. Next, we need to add the method to ViewControllerA that is called when any segue is performed, because of this we need to detect which segue was called and then do something.

    (接下来,我们需要将方法添加到执行任何segue时要调用的ViewControllerA中,因此,我们需要检测调用了哪个segue,然后执行某些操作。)

    In our example we will check for "showDetailSegue" and if that's performed we will pass our BOOL value to ViewControllerB

    (在我们的示例中,我们将检查"showDetailSegue" ,如果执行了此操作,则将BOOL值传递给ViewControllerB)

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

    If you have your views embedded in a navigation controller you need to change the method above slightly to the following

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

     -(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; } } 

    This will set isSomethingEnabled in ViewControllerB to BOOL value YES .

    (这会将ViewControllerB isSomethingEnabled设置为BOOLYES 。)

Passing Data Back

(传回数据)

To pass data back from ViewControllerB to ViewControllerA you need to use Protocols and Delegates or Blocks , the latter can be used as a loosely coupled mechanism for callbacks.

(通过从数据回ViewControllerBViewControllerA需要使用协议和代表 ,后者可以被用作用于回调松散耦合机制。)

To do this we will make ViewControllerA a delegate of ViewControllerB .

(要做到这一点,我们将ViewControllerA的委托ViewControllerB 。)

This allows ViewControllerB to send a message back to ViewControllerA enabling us to send data back.

(这使ViewControllerB可以将消息发送回ViewControllerA从而使我们能够将数据发送回去。)

For ViewControllerA to be a delegate of ViewControllerB it must conform to ViewControllerB 's protocol which we have to specify.

(对于ViewControllerA是的委托ViewControllerB它必须符合ViewControllerB我们有指定的协议。)

This tells ViewControllerA which methods it must implement.

(这告诉ViewControllerA它必须实现哪些方法。)

  1. In ViewControllerB.h , below the #import , but above @interface you specify the protocol.

    (在ViewControllerB.h ,在#import下方,但在@interface上方,指定协议。)

     @class ViewControllerB; @protocol ViewControllerBDelegate <NSObject> - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item; @end 
  2. next still in the ViewControllerB.h you need to setup a delegate property and synthesize in ViewControllerB.m

    (接下来仍然在ViewControllerB.h您需要设置一个delegate属性并在ViewControllerB.m合成)

     @property (nonatomic, weak) id <ViewControllerBDelegate> delegate; 
  3. In ViewControllerB we call a message on the delegate when we pop the view controller.

    (在ViewControllerB ,当我们弹出视图控制器时,我们在delegate上调用一条消息。)

     NSString *itemToPassBack = @"Pass this value back to ViewControllerA"; [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack]; 
  4. That's it for ViewControllerB .

    (这就是ViewControllerB 。)

    Now in ViewControllerA.h , tell ViewControllerA to import ViewControllerB and conform to its protocol.

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

     #import "ViewControllerB.h" @interface ViewControllerA : UIViewController <ViewControllerBDelegate> 
  5. In ViewControllerA.m implement the following method from our protocol

    (在ViewControllerA.m ,从我们的协议中实现以下方法)

     - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item { NSLog(@"This was returned from ViewControllerB %@",item); } 
  6. Before pushing viewControllerB to navigation stack we need to tell ViewControllerB that ViewControllerA is its delegate, otherwise we will get an error.

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

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

References (参考文献)

  1. Using Delegation to Communicate With Other View Controllers in the View Controller Programming Guide

    (《 View Controller编程指南》中的使用委派与其他View Controller通信)

  2. Delegate Pattern

    (代表图案)

NSNotification center It's another way to pass data.

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

// add observer in controller(s) where you want to receive data
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeepLinking:) name:@"ha

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...