如何在2个根视图控制器之间进行切换

时间:2012-03-05 16:29:42

标签: iphone objective-c xcode uinavigationcontroller uiapplicationdelegate

我有一个带有两个rootViewControllers的游戏 - 一个用于菜单,另一个用于游戏本身。

当用户在游戏和菜单之间切换时,我想切换rootViewController。最终我的问题是,最好的方法是什么?或者是否有另一种切换堆栈的方法比使用2个rootViewControllers更有意义?

就目前而言,我的appDelegate中有一个navigationController实例。当我想切换rootViewController时,我初始化一个新的navigationController,设置它的rootVC,然后将其设置为appDelegate中navController的实例。从菜单转换到游戏的代码如下所示:

//Initialise the new Root Controller
GameViewController *rootController = [[GameViewController alloc] init];

UINavigationController *newNavController = [[UINavigationController alloc] initWithRootViewController:rootController];
[rootController release];   
newNavController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:newNavController animated:YES];

//Setting the appDelegate's navController to the new navController allows the menu to dealloc. 
//This must happen AFTER the newNavController has been loaded. 
MiniAppDelegate *appDelegate = (MiniAppDelegate *)[[UIApplication sharedApplication] delegate]; 
appDelegate.navController = newNavController;
[newNavController release];

这是不好的做法?我的应用程序从后台恢复时遇到问题,我认为这可能是导致它的原因。

3 个答案:

答案 0 :(得分:0)

你可以做这样的事情

首先将GameViewController作为字段添加到菜单控制器

然后用它来显示它(在菜单控制器类中)

if(myGameViewController == nil) {
     myGameViewController = [[GameViewController alloc]
     initWithNibName: @"GameView" bundle: nil];
}
[self presentModalViewController: self.myGameViewController animated:YES];

然后用它来删除它(在GameViewController类中)

[self.parentViewController dismissModalViewControllerAnimated: YES];

什么是打开游戏视图作为菜单视图的子项这至少需要GameViewController是UIViewController而不是RootViewController。

答案 1 :(得分:0)

通过不提供模态视图控制器,但使用管理底层视图控制器的UIViewController,您可能会顺利进行。

与此类似:

// MainNavigationController extends UINavigationController

@property (nonatomic,retain) UIViewController childViewController

-(void)viewDidLoad {
    self.childViewController = [MenuViewController alloc] initWithNibName...];
    [self pushViewController:childView...];
}

-(void)launchGame {
    self.childViewController = [GameViewController alloc] ... ];
    self.viewControllers = [NSArray array];
    [self pushViewController:childView...];
}

这样您就可以随时拥有对当前视图控制器的引用,并在一个地方管理它们的显示。

您还应该向两个子视图控制器传递对MainNavigationController的引用,以便您可以使用委托方法。

修改

澄清有关第一条评论的内容:是的,MainNavigationController是应用程序的起点,用于处理菜单和游戏本身的显示。

线self.viewControllers = [NSArray array]用于在启动游戏时清空当前视图控制器列表。这样做是为了用游戏替换菜单而不是仅仅推动它。这样,当用户进入菜单,游戏,菜单等时,您没有8个视图控制器。

在玩游戏时,将使用类似的方法打开菜单:按钮会要求MainViewController打开菜单。您可以使用与launchGame方法相同的方式,也可以然后将其作为保持游戏状态的模态方式,或者在此之前或之前放置较小的游戏内菜单 - 从那里处理事情的许多方法。

答案 2 :(得分:0)

你不能只使用你的主菜单控制器作为rootView控制器并用它来模拟推送其他每个视图(或者只是在iOS5中使用新的[self presentViewController:...])?

即使您有多个菜单视图,也可以通过[UIApplication sharedApplication]的rootView控制器随时访问主菜单?甚至[self presentingViewController]