为什么即使未将视图控制器显式添加为子项,也会调用外观方法?

时间:2013-04-02 21:20:16

标签: ios uiviewcontroller

在研究容器视图控制器以尝试重构某些代码时,我遇到了一些我不理解的东西。

Apple文档告诉我,为了让子视图控制器获取其外观方法,必须使用addChildViewController:

将它们作为子项添加到父视图控制器中

这让我很困惑,因为我的代码不使用任何容器视图控制器方法,但我的所有子视图控制器都收到了viewWillAppear:消息。

我已将代码简化为这个简单的示例,您将在其中看到" ChildViewController:viewWillAppear:"尽管调用了addChildViewController:

,但仍在调试日志中
@interface ChildViewController : UIViewController
@end

@implementation ChildViewController

- (void)loadView {
    self.view = [[UIView alloc] initWithFrame:CGRectMake(10.0f, 10.0f, 250.0f, 250.0f)];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"ChildViewController:viewWillAppear:");
}

@end


@interface RootViewController : UIViewController
@property (strong) ChildViewController *cvc;
@end

@implementation RootViewController
@synthesize cvc;
- (void)loadView {
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(10.0f, 10.0f, 500.0f, 500.0f)];
    cvc = [[ChildViewController alloc] init];
    [view addSubview:[cvc view]];
    self.view = view;
}

@end


@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = [[RootViewController alloc] init];
    [self.window makeKeyAndVisible];

    return YES;
}

@end

为什么这样做?

1 个答案:

答案 0 :(得分:1)

调用addSubview的过程会导致视图显示,从而产生loadViewviewDidLoadviewWillAppearviewDidAppear等。,电话。 addChildViewController(以及您应该对didMoveToParentViewController的调用)不会影响这一点。

您调用addChildViewController以确保您的控制器层次结构与视图层次结构保持同步。如果不这样做,则不会将某些事件传递给子控制器(例如旋转事件)。此外,通过执行addChildViewController,您的控制器将为您保留,而无需维护您自己的属性以跟踪子控制器。

如果您看到WWDC 2011 - #201 Implementing UIViewController Containment,它将讨论保持视图层次结构和控制器层次结构同步的重要性。