Container View Controllers - notify parent of action

soleil picture soleil · Feb 19, 2013 · Viewed 8k times · Source

Say I have a custom container view controller (MainViewController) where I do something like this:

- (void)viewDidLoad
{
    [super viewDidLoad];        

    HomeViewController *homeVC = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
    [self addChildViewController:homeVC];
    [self.view addSubview:homeVC.view];

}

The HomeViewController will have a button, such as "go", that when pressed will need to advance to the next view controller. So I need to notify the MainViewController of this action. What is the best way to do this?

I'm using a custom container because I need to do custom transitions between the view controllers. When "go" is pressed, some of the views on the HomeViewController will animate while the views from the new view controller are animating into place.

Obviously I could give the HomeViewController a property of type MainViewController and make calls that way, but I'm hoping that there is a cleaner way with the container view controller API.

Answer

Eric Qian picture Eric Qian · Feb 19, 2013

You can either use delegate or block;

Using delegate

Create a protocol :

@protocol SomeProtocol <NSObject>
- (void)someAction; 
@end 

Just declare a delegate in HomeViewController.h like this:

id<SomeProtocol> delegate; 

and then in MainViewController's viewDidLoad set it like this:

homeVC.delegate = self;
//some where in MainViewController implement the protocol method
-(void)someAction
{
    //do something
}

then when you press the button in homeVC, just simply call:

if ([self.delegate respondsToSelector:@selector(someAction)]) {
    [self.delegate someAction];
}

Using Block:

In HomeViewController.h declare a block property:

typedef void (^ActionBlock)();

@property (nonatomic, copy) ActionBlock block;

then in MainViewController ViewDidLoad:

homeVC.block = ^(){
    //do something
};

then when you press the button in homeVC, just simply call:

self.block();