如果您有子视图并且这些子视图有自己的视图控制器,您应该遵循自定义容器控制器模式。请参阅创建自定义容器视图控制器了解更多信息。
假设您已经遵循了自定义容器模式,当您想要更改"内容视图"的子视图控制器(及其相关视图)时,您可以通过编程方式进行操作,例如:
UIViewController *newController = ...
UIViewController *oldController = ...
newController.view.frame = oldController.view.frame;
[oldController willMoveToParentViewController:nil];
[self addChildViewController:newController];
[self transitionFromViewController:oldController
toViewController:newController
duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
}
completion:^(BOOL finished) {
[oldController removeFromParentViewController];
[newController didMoveToParentViewController:self];
}];
如果你用这种方式实现,就不需要为内容视图的控制器提供任何委托协议接口(除了iOS已经提供的在自定义容器中管理子视图控制器方法)。
顺便说一下,这假定与该内容视图关联的初始子控制器是以这种方式添加的:
UIViewController *childController = ... // instantiate the content view's controller any way you want
[self addChildViewController:childController];
childController.view.frame = ... // set the frame any way you want
[self.view addSubview:childController.view];
[childController didMoveToParentViewController:self];
如果您想让子控制器告诉父控制器更改与内容视图相关联的控制器,您可以执行以下操作:
- 定义一个协议:
@protocol ContainerParent <NSObject>
- (void)changeContentTo:(UIViewController *)controller;
@end
定义父控制器符合这个协议,例如:#import <UIKit/UIKit.h>
#import "ContainerParent.h"
@interface ViewController : UIViewController <ContainerParent>
@end
在父控制器中实现changeContentTo
方法(与上述大致相同):
- (void)changeContentTo:(UIViewController *)controller
{
UIViewController *newController = controller;
UIViewController *oldController = ...
newController.view.frame = oldController.view.frame;
[oldController willMoveToParentViewController:nil];
[self addChildViewController:newController];
[self transitionFromViewController:oldController
toViewController:newController
duration:1.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
}
completion:^(BOOL finished) {
[oldController removeFromParentViewController];
[newController didMoveToParentViewController:self];
}];
}
现在子控制器可以使用此协议来引用iOS为您提供的self.parentViewController
属性:
- (IBAction)didTouchUpInsideButton:(id)sender
{
id <ContainerParent> parentViewController = (id)self.parentViewController;
NSAssert([parentViewController respondsToSelector:@selector(changeContentTo:)], @"Parent must conform to ContainerParent protocol");
UIViewController *newChild = ...
[parentViewController changeContentTo:newChild];
}