故事板 – 回合制游戏的工作stream程

我正在创build一个基于回合的游戏,并想知道我的工作stream程的正确过程。 目前我有以下几点:

主视图控制器(它有一个UITableView
单击第1节中的行>加载path为1的UINavigationController
点击第2节中的行>加载path为2的UINavigationController

举个例子:
path1 – 发挥轮到你
path2 – 猜你的回合

每个path都有大约4-5个加载到导航控制器的UIViewControllers

现在我处于path2完成的阶段,用户也应该轮到他们(也就是path2,path1)。

什么是完成这个正确的方法? 应该从最后一个控制器在path2>导致path1创build一个segue。问题是path2有一个UIViewController有一个UIImageView与大图像,它会在内存中四处闲逛。 理想情况下,在用户启动path1之前(path2完成之后)

我曾尝试popToRootViewControllerAnimated但它不工作,当我们想movetopath2 。 我们可以在NSUserDefaults中存储一些检查点,然后继续进行检查, 但是这种方法在这种情况下不起作用。

 [self.navigationController popToRootViewControllerAnimated:YES]; 

最后我find了解决办法如下:
从下面的工作代码开始,根据您的应用程序逻辑进行更改
你的工作流程

ViewController.m文件

  #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ if (indexPath.section == 0) { UIStoryboard *mainStoryBoard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; PathOneViewController *pathController = [mainStoryBoard instantiateViewControllerWithIdentifier:@"PathOneViewController"]; [self.navigationController pushViewController:pathController animated:YES]; } else { UIStoryboard *mainStoryBoard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; PathTwoViewController *pathController = [mainStoryBoard instantiateViewControllerWithIdentifier:@"PathTwoViewController"]; [self.navigationController pushViewController:pathController animated:YES]; } } 

PathOneDetailViewController.m文件

  - (IBAction)actionMoveToPathTwo:(id)sender { // Move to path two AppDelegate *appDelegateTemp = [[UIApplication sharedApplication]delegate]; UIViewController* rootController = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"PathTwoViewController"]; UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:rootController]; appDelegateTemp.window.rootViewController = navigation; } - (IBAction)actionMoveToHome:(id)sender { // Move to table View AppDelegate *appDelegateTemp = [[UIApplication sharedApplication]delegate]; UIViewController* rootController = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"ViewController"]; UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:rootController]; appDelegateTemp.window.rootViewController = navigation; } 

PathTwoDetailViewController.m文件

 - (IBAction)actionMoveToHome:(id)sender { // Move to table View AppDelegate *appDelegateTemp = [[UIApplication sharedApplication]delegate]; UIViewController* rootController = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"ViewController"]; UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:rootController]; appDelegateTemp.window.rootViewController = navigation; } - (IBAction)actionMoveToPath1:(id)sender { // Move to path one AppDelegate *appDelegateTemp = [[UIApplication sharedApplication]delegate]; UIViewController* rootController = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"PathOneViewController"]; UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:rootController]; appDelegateTemp.window.rootViewController = navigation; } 
  1. 从path2发出通知

  2. 请确保您在Home View Controller中订阅该通知

  3. 在Home View Controller的通知处理程序方法中,调用当前导航控制器的popToRootViewControllerAnimated:

  4. 手动调用segue开始path1。

对我而言,答案实际上是一个更简单的方法。 将ViewController引用添加到Path2的起始视图控制器。 然后简单地更改UINavigationController堆栈中的视图控制器。 由于导航控制器不分类或不需要这个工作正常。

 - (IBAction)completeButtonPressed:(id)sender { NSLog(@"complete button pressed"); Path2ViewController *path2StartVC = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"Path21VC"]; [self.navigationController setViewControllers:[NSArray arrayWithObject:path2StartVC] animated:YES]; } 

我将把一个示例项目放到github上以供参考。

我build议你设置你的第一个控制器为UINavigationController,并将其根控件设置为“Home View Controller”(UITableView)。 我现在称之为根控制器。 然后,您可以保持应用程序结构的其余部分与现在一样,每个路由使用一个UINavigation控制器。

这会给你能够调用根导航控制器popToRootViewControllerAnimated:的好处 。 在这种情况下,将是您的“家庭视图控制器”。 这有一个轻微的缺点,那就是你的path不能在path上的当前导航控制器上调用popToRootViewControllerAnimated:。 因为这会让你回到你所在的path的开始。

但是通过保持对根控制器的引用可以很容易地解决这个问题。 我将通过inheritanceUINavigationController并仅添加一个存储对根视图控制器的引用的属性来实现。 当视图控制器从表视图转换到控制两个path之一的导航控制器时,需要完成这个任务。 我认为prepareForSegue:发件人:这将是你最好的select。

至于你担心UIImageView留在内存中。 你不需要担心。 当视图控制器卸载它也将卸载UIImageView。 你可以保持一个视图控制器卸载的唯一方法是在另一个视图控制器中保持强烈的引用。 有时你想要例如。 父母/孩子的关系有时你不例如。 在视图控制器之间延续。 但是在视图控制器之间传递属性应该没问题。 有关更多信息,请查看View Controller Guide

解决这个问题有很多不同的方法。 所以,我会以自己的答案为出发点,并将其适应于最适合您的应用程序和代码风格的未来。