我正在创建一个基于回合制的游戏,并想知道我的工作流程的正确过程。目前我有以下几点:
主视图控制器(具有UITableView
)
点击第1部分中的行>用路径1加载UINavigationController
点击第2部分中的行>用路径2加载UINavigationController
举个例子:
路径1 - 轮到你了
路径2 - 猜你轮到你了
每个路径都有大约4-5 UIViewControllers
加载到导航控制器中。
现在我处于一旦路径2完成的阶段,用户也应该轮到他们(即路径2然后路径1)。
完成此操作的正确方法是什么?我应该从路径2中的最后一个控制器创建一个segue>导致路径1.问题是路径2有一个UIViewController
,其UIImageView
有一个大图像,它会在内存中徘徊。理想情况下,在用户启动路径1之前(路径2完成之后)将其清除
答案 0 :(得分:2)
我已经尝试了popToRootViewControllerAnimated
但是当我们需要 movetopath2 时它无法正常工作。
我们可以在NSUserDefaults中存储一些检查点,然后相应地删除但在这种情况下该方法不起作用。
[self.navigationController popToRootViewControllerAnimated:YES];
最后我找到了解决方案如下:
从下面的工作代码开始,根据您的应用逻辑进行更改
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 :(得分:0)
从路径2发送通知
请务必在Home View Controller
在Home View Controller中的通知处理程序方法中,调用
当前导航控制器的popToRootViewControllerAnimated:
。
手动调用segue开始路径1.
答案 2 :(得分:0)
我建议您将第一个控制器设置为UINavigationController并将其根控件设置为“Home View Controller”(UITableView)。我现在称之为根导航控制器。然后,您可以保持应用程序结构的其余部分与现在相同,每个路径都有一个UINavigation控制器。
这将使您能够调用根导航控制器popToRootViewControllerAnimated:。在这种情况下,你的“家庭视图控制器”。这有一个轻微的缺点,就是你的路径,你不能只在路径上调用当前导航控制器上的popToRootViewControllerAnimated:。因为这会使您返回到您所在路径的开头。
但是通过保持对根导航控制器的引用可以很容易地解决这个问题。我将通过继承UINavigationController并添加一个存储对根视图控制器的引用的属性来做。当视图控制器从表视图转换到控制两个路径之一的导航控制器时,需要完成分配。我认为prepareForSegue:sender:是处理此问题的最佳选择。
至于你担心UIImageView会留在内存中。你不必担心它。当视图控制器卸载时,它也将卸载UIImageView。保持视图控制器不被卸载的唯一方法是在另一个视图控制器中保持对它的强引用。有时你想要的,例如。父母/子女的关系有时你不会例如。视图控制器之间的segue。但是在视图控制器之间传递属性应该没问题。有关详细信息,请查看View Controller Guide
有很多不同的方法可以解决这个问题。所以,我会把我的答案作为一个起点,并根据你的应用程序和代码风格的未来进行调整。
答案 3 :(得分: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上以供参考。