tutorial net
*********WOOOOOOW *********
We're happy to see you're enjoying our races (already 5 pages viewed today)! You can keep checking out by becoming a member of the tutorial net community. It's free!
You will also be able to keep track of your race progress, practice on exercises, and chat with other members.

Share
Go down
Admin
Posts : 200
Join date : 2017-11-11
Age : 27
Location : algeria
View user profilehttp://www.tutorial-net.com

free courses IOS - Passing Data between View Controllers

on Mon Apr 02, 2018 10:07 pm
I'm new to iOS and, Objective-C and the whole MVC paradigm and I'm stuck with the following:

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 UITableView controller and I have enabled multiple selections.

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?

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.

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

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.

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

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

in ViewControllerB.h create a property for the BOOL

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

#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.
Code:
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.

Passing Data Forward using Segues

If you are using Storyboards you are most likely using segues and will need this procedure to pass data forward. 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:

in ViewControllerB.h create a property for the BOOL

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

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

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. In our example we will check for "showDetailSegue" and if thats performed we will pass our BOOL value to ViewControllerB
Code:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([segue.identifier isEqualToString:@"showDetailSegue"]){
        ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
        controller.isSomethingEnabled = YES;
    }
}
This will set isSomethingEnabled in ViewControllerB to BOOL value YES.

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.

To do this we will make ViewControllerA a delegate of ViewControllerB. This allows ViewControllerB to send a message back to ViewControllerA enabling us to send data back.

For ViewControllerA to be delegate of ViewControllerB it must conform to ViewControllerB's protocol which we have to specify. This tells ViewControllerA which methods it must implement.

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

@class ViewControllerB;

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

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

NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
[self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
That's it for ViewControllerB. Now in ViewControllerA.h, tell ViewControllerA to import ViewControllerB and conform to its protocol.

#import "ViewControllerB.h"

@interface ViewControllerA : UIViewController <ViewControllerBDelegate>
In ViewControllerA.m implement the following method from our protocol

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

ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.delegate = self
[[self navigationController] pushViewController:viewControllerB animated:YES];
Back to top
Permissions in this forum:
You cannot reply to topics in this forum