容器视图控制器 - 通知动作的父(Container View Controllers - noti

2019-07-20 04:54发布

说我有一个自定义的容器视图控制器(MainViewController),我做这样的事情:

- (void)viewDidLoad
{
    [super viewDidLoad];        

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

}

该HomeViewController将有一个按钮,如“走出去”,按下时将需要前进到下一个视图控制器。 所以,我需要通知这个动作的MainViewController。 做这个的最好方式是什么?

我使用的是自定义的容器,因为我需要做的视图控制器之间的自定义转换。 当“走出去”被按下时,一些对HomeViewController的意见,同时将在新视图控制器的意见动画到位动画。

很显然,我可以给HomeViewController类型MainViewController的属性和拨打电话这种方式,但我希望有一个与容器视图控制器API一个更清洁的方式。

Answer 1:

您可以使用委托或块;

使用代理

创建一个协议:

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

只需要声明一个委托在HomeViewController.h这样的:

id<SomeProtocol> delegate; 

然后在MainViewController的viewDidLoad设置是这样的:

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

那么当你按下homeVC按钮,只需简单地调用:

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

使用Block:

在HomeViewController.h声明块属性:

typedef void (^ActionBlock)();

@property (nonatomic, copy) ActionBlock block;

然后在MainViewController viewDidLoad中:

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

那么当你按下homeVC按钮,只需简单地调用:

self.block();


Answer 2:

有太多的另一种方式......每个视图控制器具有parentViewController因此使用,你可以做这个属性...

MainViewController定义要执行的操作的方法...

- (void)someMethod:(BOOL)someParam;

然后在HomeViewController你可以做...

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

HTH :)



Answer 3:

这是一个很常见的模式。 家长会的实际情况,将处理的动作,通过提供protocol和默认的扩展 。

在斯威夫特3:

父视图控制器:

protocol SomeProtocol {
    func foo()
}

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

儿童视图控制器:

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


文章来源: Container View Controllers - notify parent of action