Container View Controllers - notify parent of action

霸气de小男生 提交于 2019-11-28 23:21:21

问题


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.


回答1:


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();



回答2:


There's another way too... Every view controller has a parentViewController property so using that you can do this...

In MainViewController define a method for the action you want to perform...

- (void)someMethod:(BOOL)someParam;

Then in HomeViewController you can do...

MainViewController* parent = (MainViewController*)[self parentViewController];
[parent someMethod:paramValue];

HTH :)




回答3:


This is a very common pattern. The parent will be the actual instance that will handle the action, by providing a protocol and a default extension.

In Swift 3:

Parent view controller:

protocol SomeProtocol {
    func foo()
}

extension ParentViewController: SomeProtocol {
    func foo() {
        // Parent handles it
    }
}

Child view controller:

 @IBAction func tapGo(_ sender: Any) {
    (parent as? SomeProtocol)?.foo()
 }


来源:https://stackoverflow.com/questions/14968321/container-view-controllers-notify-parent-of-action

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!