2014-01-29 30 views
4

我正在创建基于回合的游戏并希望知道我的工作流程的正确流程。目前我有以下:故事板 - 基于回合的游戏的工作流程

主页视图控制器(其具有UITableView
点击行从第1节>加载具有路径1
点击行从第2条一UINavigationController>加载一个UINavigationController与路径2

举个例子:
路径1 - 发挥轮到你了
路径2 - 猜轮到你

每个路径有大约4-5 UIViewControllers装载入T他导航控制器。

现在我处于一旦路径2完成的阶段,用户也应该轮到他们(即采取路径2然后路径1)。

完成此操作的正确方法是什么?我应该从路径2>中的最后一个控制器创建一个segue,导致路径1.问题是路径2有一个UIViewController,它有一个大的图像在内的UIImageView,它将在内存中四处移动。理想情况下,用户启动路径1之前被清除,例如,(后路径2完成)

回答

0

为我工作的回答竟是一个更简单的方法。将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上以供参考。

0
  1. 火从路径的通知2

  2. 确保您订阅主页视图控制器

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

  4. 手动调用SEGUE启动路径1

+0

谢谢。对于第1项,您的意思是创建一条通知,指出路径2已经开始或结束?对于第3项,您说一旦通知被称为调用当前导航控制器popToRoot。与此问题将是根视图控制器将是路径1根视图控制器...它不会? – StuartM

+0

我建议在路径2结束时发出通知,所以父VC需要显示第二个导航控制器。我想你不一定需要解开第一个导航控制器。您可能只需将通知窗口中的导航VC展开,然后转到另一个导航窗口即可。 – Macondo2Seattle

+0

感谢您的回答,事实上,我只需在导航控制器上使用'setViewControllers'方法就可以完成此操作,只将path2作为路径加载,因此将剩余的路径分开。 – StuartM

0

我建议你设置你的第一个控制器作为一个UINavigationController和其根控制设置为“主视图控制器”(UITableView的)。我现在称之为根控制器。然后,您可以保持应用程序结构的其余部分与现在一样,并为每个路径使用一个UINavigation控制器。

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

但是,通过保持对根控制器的引用,很容易解决这个问题。我将通过继承UINavigationController并只添加一个存储对根视图控制器的引用的属性来实现。当视图控制器从表视图转换到控制两个路径之一的导航控制器时,需要完成分配。我认为prepareForSegue:sender:将是你处理这个问题的最佳选择。

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

有可能有很多不同的方式来解决这个问题。所以,我会以我的答案为出发点,并根据您的应用程序和代码风格的未来最适合的方式进行调整。

+0

感谢@Rob,能否详细介绍一下你引用的'UIImageView'参考。我用'UIViewController'的强引用创建了'UIImageView'。我将一个强大的UIImage引用传递给一个新的控制器,然后在viewDidLoad中将该图像放入'UIImageView'中。我将同样的步骤重复进入下一个将'UIImage'通过segue传递给最终控制器的强引用。 – StuartM

+0

@StuardM我在更新了这篇文章后,重读了我写的内容,并非100%正确。谢谢你收到。 – Rob

2

我已经试过popToRootViewControllerAnimated但它不工作的时候,我们希望movetopath2。 我们可以在NSUserDefaults中存储一些检查点,然后相应地继续执行,但是这种方法在这种情况下不起作用。

[self.navigationController popToRootViewControllerAnimated:YES]; 

最后我找到了解决办法如下:
开始下面的工作代码,并改变它根据你的应用程序逻辑
Your Work Flow

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; 

} 
+0

感谢您的详细回复。事实上,我可以用简单的方法在导航控制器上简单地使用'setViewControllers'方法来完成。这dealloc的旧控制器和加载新的根。请参阅下面的答案。谢谢 – StuartM

相关问题