2

I am a beginner, and I have a project in which I need to pass data back from a childviewcontroller. Specifically, I have a picker view in my container and I want to be able to use it to select an option (say to simplify just a color to chose from an array of ten colours). Then I would like to be able to access the chosen color in my parent view controller and do something with it. I have researched this for a couple of days now and the closest answer to what I am looking for I found in a related question on S.O. Here it is:

"Regarding passing value to the containerView controller, you can make a property in the ChildViewController of the value you want it to be passed. Then in your ParentViewController do something like the following:

self.ChildViewController.yourProperty = yourValue

The opposite can be done in 4 ways:

You can make a delegate protocol to communicate the data between your controllers.

You can post a notification in your ChildViewController and add the parent controller as an observer.

You can use KVO.

And the easiest way out, you can make a property in your parentviewController and access it like the following:"

((YourParentViewControllerClassType *)self.parentViewController).yourParentProperty = TheValueYouWant;

Now, I would like to try the fourth option first as delegation, kvo and so on are options I have read about but not ready to tackle yet. What I would need help with is the last option.

Say I had a property in my child view controller where I store the chosen color. Something like:

@interface ViewController ()

@property NSString *ChosenColorInChildVC;

@end

And then, later on:

self.ChosenColorInChildVC = [self pickerView:myPickerView titleForRow:[myPickerView selectedRowInComponent:1] forComponent:1]];

how would I pass that value using the proposed:

((YourParentViewControllerClassType *)self.parentViewController).yourParentProperty = TheValueYouWant;

Can someone dumb it down a little further for me? Thanks

Paul
  • 1,045
  • 4
  • 22
  • 46

3 Answers3

5

I'm going to explain you with an example how delegation works.

Edit your ChildViewController.h like this:

@protocol ChildViewControllerDelegate; 

@interface ChildViewController : UIViewController

@property (weak)id <ChildViewControllerDelegate> delegate;

@end

@protocol ChildViewControllerDelegate <NSObject > 

- (void) passValue:(UIColor *) theValue;

@end

On your ChildViewController.m when you want to pass something back to the ParentViewController , do like this:

 - (void) myMethod
 {
   [delegate passValue:[UIColor redColor]]; // you pass the value here
 }

On your ParentViewController.h

#import "ChildViewController.h"

@interface ParentViewController : UIViewController <ChildViewControllerDelegate >  // you adopt the protocol
{
}

On your ParentViewController.m:

- (void) passValue:(UIColor *) theValue
   {
      //here you receive the color passed from ChildViewController
   }

Now be careful. Everything will work only if you set the delegate. So when you declare ChildViewController inside your ParentViewController class, do like this:

ChildViewController * controller = [[ChildViewController alloc]initWithiNibName:@"ChildViewController"];
controller.delegate = self; //without this line the code won't work!
metronic
  • 455
  • 5
  • 13
  • Hi metronic. Thanks for this, it's been a huge help. I have done everything you said and (I think) understood the logic behind most of it. Except for the last bit you wrote: "On your ParentViewController.m: -(void) passValue:(UIColor *) theValue { //here you receive the color passed from ChildViewController}" I understand more or less the idea behind it, but how does it actually work in practice. Say I have chosen red in my container. how would I access it in my parent by using this method? something like: UIColor *myReceivedColor = [self passValue:???]; – Paul Jan 24 '16 at 12:54
  • No, you'll receive the data inside the method - (void) passValue:(UIColor *) theValue; Put a breakpoint in that method to be sure that it's working, you can access it like this: UIColor *myReceivedColor = theValue; – metronic Jan 24 '16 at 13:02
  • OK. Sorry about this. I am not familiar at all with the concept of "receiving values" inside a method. So, to make sure I understand you. Do I need to write anything inside the method -(void) passValue:(UIColor *) theValue{} in my Parent? And if I want to access the color in my parent... I've tried to write litteraly UIColor *myReceivedColor = theValue; and it comes back with "used of undeclared identifier: "theValue". I have also tried UIColor *myReceivedValue = [self passValue:theValue]; – Paul Jan 24 '16 at 13:16
  • I have also tried this [self passValue:[self.controller.colors objectAtIndex:[self.controller.myPickerView selectedRowInComponent:0]]]; – Paul Jan 24 '16 at 13:37
  • I think I know why it's not working. Your line: ChildViewController * controller = [[ChildViewController alloc]initWithiNibName:@"ChildViewController"]; prompts an error: no visible @interface for "ChildViewController" declares the selector "initWithNibName' – Paul Jan 24 '16 at 21:32
0

@metronic is right; use delegation.

Also typically you will include the sender in your delegate methods:

-(void) childViewController:(ChildViewController*)viewController passValue:(UIColor*) theValue 
BoombaleOsby
  • 301
  • 4
  • 7
0

Noted: this is very important.

Write protocol declaration code above the #import lines e.g.

@protocol -----

@end

import ----

@interface classname ---

anson
  • 1,054
  • 10
  • 12