2

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

Apple 文档告诉我,为了让子视图控制器调用它们的外观方法,它们必须作为子视图控制器添加到父视图控制器中addChildViewController:

这让我感到困惑,因为我的代码没有使用任何容器视图控制器方法,但我所有的子视图控制器都收到了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

为什么这行得通?

4

1 回答 1

1

调用过程addSubview将导致视图出现,从而导致loadView, viewDidLoad, viewWillAppear,viewDidAppear等调用。(addChildViewController以及didMoveToParentViewController您也应该这样做的电话)不会影响这一点。

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

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

于 2013-04-02T21:53:36.953 回答