UIViewController遏制做得对吗?

时间:2012-07-30 17:31:04

标签: iphone objective-c cocoa-touch ipad ios5

我正在开发一个具有类似于网站的导航菜单的iPad应用程序:想象屏幕左侧的菜单带有一系列按钮,每次点击按钮时都会显示不同的控制器。 / p>

由于某些图形限制,我不能使用os提供的任何容器控制器,因此我决定将自己的容器类编写为概念类似于UITabBarController。我想知道我使用的方法是否正确,尤其是addChildViewController:didMoveToParentViewController:的使用

在我的容器的init中,我这样做:

MAHomeController *home = [[MAHomeController alloc] initWithNibName:@"MAHomeController" bundle:nil];
[self addChildViewController:home];
[home didMoveToParentViewController:self];
homeIndex = [self.childViewControllers indexOfObject:home];
[home release];

MAConfigHomeController *config = [[MAConfigHomeController alloc] initWithNibName:@"MAConfigHomeController" bundle:nil];
[self addChildViewController:config];
[config didMoveToParentViewController:self];
configIndex = [self.childViewControllers indexOfObject:config];
[config release];

MAViewerHomeController *viewer = [[MAViewerHomeController alloc] initWithNibName:@"MAViewerHomeController" bundle:nil];
[self addChildViewController:viewer];
[viewer didMoveToParentViewController:self];
viewerIndex = [self.childViewControllers indexOfObject:viewer];
[viewer release];

如您所见,我一次添加所有内容控制器,并在添加后立即调用didMoveToParentViewController:。这个可以吗?

然后处理内容之间导航的方法就是这样的:

// some stuff removed for brevity, mostly configuration stuff
UIViewController *fromCtrl = [self.childViewControllers objectAtIndex:currentIndex];
UIViewController *toCtrl = [self.childViewControllers objectAtIndex:index];
self.currentIndex = index;
[self transitionFromViewController:fromCtrl toViewController:toCtrl duration:0.7 options:opts animations:^(void) {} completion:^(BOOL finished) {
        if (completion)
            completion();
    }];

正如您在完成块中看到的那样,我不会在新转换的控制器上调用didMoveToParentViewController:,因为它之前已添加到容器的childViewControllers。并且我也不会删除旧控制器,因为实际上它保留在childViewCOntrollers数组中,直到容器控制器被释放。

所有事件都正确路由,甚至是嵌套在3个主要控件中的子控制器。内存也不应该是一个问题,因为在模拟内存警告时,不可见控制器的视图在显示时被卸载并重新加载。

这个设计好吗?

1 个答案:

答案 0 :(得分:1)

如果你阅读iOS开发中心的View Controller指南,addChildViewController上没有约束:和didMoveToParentViewController:这将使你所做的顺序不正确。

我唯一能做的就是延迟这一点,以便在实际显示视图之前iOS不会加载nib。我敢打赌,如果你运行探查器,你将在初始化父容器时加载所有的nib。