1

OK, I have a RootViewController.m and defined a method in there:

-(void)doSomethingParent
{
    NSLog(@"Parent is doing something after child has asked");
}

I then added a childViewController.view like so:

if (self.child == nil) {

    ChildViewController *cvc = [[ChildViewController alloc]
                                initWithNibName:nil bundle:nil];
    self.child = cvc;
    [cvc release];

}    
[self.view insertSubview: child.view atIndex:0];

Now, I thought it would be very useful indeed if I could call my doSomethingParent method from the child. So I thought I would do it like this:

 @implementation ChildViewController
@class RootViewController;


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [super doSomethingParent];

}

But xCode tells me that "-doSomethingParent" not found... but I put @class in there?! Shouldn't it find it? I don't want to import the whole thing as I thought @class would be sufficient to let the child know that the parent has a method called doSomethingParent...

I'd be very grateful for any suggestions. Thanks in advance!

n.evermind
  • 11,944
  • 19
  • 78
  • 122
  • 1
    Anything preventing you from using delegation? – Bourne Sep 21 '11 at 20:24
  • @Bourne: Yes, my ignorance. How do I do delegation in this case? Sorry, but I'm fairly new to all of this. – n.evermind Sep 21 '11 at 20:24
  • So if you're new, you should at least read some basic guides like e.g. Cocoa Fundamentals. Doing everything by trial and error will take you much longer. – macbirdie Sep 21 '11 at 20:30
  • Answered. See my answer. Explains basic delegation to pass message to RootViewController object from a ChildViewController object. – Bourne Sep 21 '11 at 20:31

3 Answers3

4

Set rootViewController object as the delegate of an object of childViewController type. And use that delegate from ChildViewController to pass messages to RootViewController.

Inside RootViewController, when you create your ChildViewController object do:

childViewController.delegate = self;

And in ChildViewController, when you want to pass a message then pass it to RootViewController as:

[delegate doSomething];

In your ChildViewController.h interface, declare an ivar:

id delegate;

Then use @property (in .h) and @synthesize (in .m) for getter and setter.

Then do the above.

Bourne
  • 10,094
  • 5
  • 24
  • 51
  • Thanks! It works, but I get a warning when trying to to do [delegate doSomethingParent]; I'm told that instance method -doSomethingParent not found (return type defaults to 'id'). I still have the @class RootViewController in there, so I still don't understand why it doesn't recognise the method? – n.evermind Sep 21 '11 at 20:41
  • #import "RootViewController.h" inside your ChildViewController.m to remove warning. And method declaration of doSomethingParent in your interface file for RootViewController. – Bourne Sep 21 '11 at 20:48
  • Thanks, works perfectly. I had a look at what others said and there was the talk about @protocol etc. I tried to implement all of this as well, but it is so much longer and (in my view) more convoluted than what you suggested. So thanks again for this very concise description. Very much appreciated! – n.evermind Sep 21 '11 at 20:56
  • How can I accept this as the right answer? For some reason, I can't see any controls anymore? Is it just my browser? Very strange. – n.evermind Sep 21 '11 at 20:57
3

super is a reference to it's superclass, not the parent view controller. You will have to keep a reference to RootViewController and pass the message to it...

...Or code a protocol and set your RootViewController as delegate of the child, so the child would be able to pass messages to RootViewController.

I prefer the second way.

Youssef
  • 3,582
  • 1
  • 21
  • 28
  • Thanks, but how do I exactly implement the delegation thingy? Where do I start? – n.evermind Sep 21 '11 at 20:27
  • 1
    [Check this question](http://stackoverflow.com/questions/626898/how-do-i-create-delegates-in-objective-c) and take a [look at this article](http://www.thepensiveprogrammer.com/2010/05/objective-c-protocols-and-delegates.html) – Youssef Sep 21 '11 at 20:30
0

Easy way (perhaps not the best way):

self.child = cvc;
cvc.myParent = self;  // give the child a reference to its parent
hotpaw2
  • 70,107
  • 14
  • 90
  • 153
  • I don't like this way. The child should not know who is his parent so that the child could be reused by another class. – AechoLiu Sep 22 '11 at 05:36
  • @Toro : It's a simplified variant of the delegation pattern. (myParent === delegate_under_another_name) – hotpaw2 Sep 22 '11 at 07:20