Call a parent view controller (through a navigationcontroller)

Solution 1:

Just like Marsson mentioned, you need to use delegate...

Here is an sample:

In your child view controller .h file:

@protocol ChildViewControllerDelegate <NSObject>
- (void)parentMethodThatChildCanCall;
@end

@interface ChildViewController : UIViewController 
{
}
@property (assign) id <ChildViewControllerDelegate> delegate;

In your child view controller .m file:

@implementation ChildViewController
@synthesize delegate;


// to call parent method:
//  [self.delegate parentMethodThatChildCanCall];

In parent view controller .h file:

@interface parentViewController <ChildViewControllerDelegate>

In parent view controller .m file:

//after create instant of your ChildViewController
childViewController.delegate = self;

- (void) parentMethodThatChildCanCall
{
  //do thing
}

Solution 2:

self.navigationController.viewControllers

Returns an array of all the view controllers in the navigation stack. The current view controller is at the top of the stack, the previous view controller is the next one down, and so forth.

So, you can do the following:

NSArray *viewControllers =     self.navigationController.viewControllers;
int count = [viewControllers count];
id previousController = [viewControllers objectAtIndex:count - 2];
if ([previousController respondsToSelector:@selector(myMethod)])
    [previousController myMethod];

If you know what class the previous controller is you can cast it explicity instead of using id.

Solution 3:

Not sure of your application logic, but you can always do this.

In your "child" controller, declare property of type parent-controller. So, in your .h file:

MySuperController *superController;
property(nonatomic, retain)MysuperController *superController;

and in your .m file:

@synthesize superController;

Before "pushing" your child controller:

MyChildController *child = ...
[child setSuperController:self];
[self.navigationController pushViewController:child animated:YES];

Then in your child controller you can simply access your super with

[this.superController myMethod:param];

I'm not going to advocate this way of coding, but it's a quick/cheap/dirty way to accomplish things.