Storyboard - Workflow for turn based game

核能气质少年 提交于 2019-12-21 17:49:17

问题


I am creating a turn based game and would like to know the correct process for my workflow. At present I have the following:

Home View Controller (which has a UITableView)
Click on row from section 1 > Loads a UINavigationController with path 1
Click on row from section 2 > Loads a UINavigationController with path 2

As an example:
path 1 - play your turn
path 2 - guess your turn

Each path has around 4-5 UIViewControllers loaded into the navigation controller.

Now I am at the stage where once path 2 is complete the user should then play their turn too (ie take path 2 then path 1).

What is the correct way to complete this? should I create a segue from the last controller in path 2 > leading to path 1. The issue is that path 2 has a UIViewController that has a UIImageView with a large image in and it would hang around in memory. Ideally it is cleared as such, before the user starts path 1 (after path 2 is complete)


回答1:


I have tried popToRootViewControllerAnimated but its not working when we want movetopath2. We can store some checkpoints in NSUserDefaults and then segue accordingly but that approach doesn't work in this case.

[self.navigationController popToRootViewControllerAnimated:YES];

Finally I have found solution as follows:
Start with below working code and change it as per your app logic

ViewController.m File

 #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 File

 - (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 File

- (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;

}



回答2:


  1. Fire a notification from path 2

  2. Be sure you subscribe to that notification in Home View Controller

  3. In the notification handler method in Home View Controller, call the current navigation controller's popToRootViewControllerAnimated:.

  4. Manually call the segue to start path 1.




回答3:


The answer that worked for me was actually a much more simple approach. Adding a ViewController reference to the starting view controller for Path2. Then simply changing the view controllers in the UINavigationController stack. As the navigation controller is not subclassed or doesn't need to be this works fine.

- (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];

}

I will drop a sample project onto github for reference shortly.




回答4:


I would suggest you set your first controller as a UINavigationController and set its root control to the "Home View Controller" (UITableView). I'll call this the root navigation controller for now on. You then can keep the rest of the app's structure the same as you have it now, with one UINavigation controller for each route.

This would give you the advantage of being able to call the root navigation controller popToRootViewControllerAnimated:. Which in this case would be your "Home View Controller". There is one slight disadvantage to this and that is with your paths you can't just call popToRootViewControllerAnimated: on the current navigation controller when on a path. Since this would return you to the beginning of the path that you are on.

But this is easily fixed by keeping a reference to the root navigation controller. Which I would do by subclassing UINavigationController and just adding a property that stores a reference to the root view controller. The assignment would need to be done while the view controllers are transitioning from the table view to the navigation controllers that control one of your two paths. I think prepareForSegue:sender: would be your best bet to handle this.

As for your worry of the UIImageView staying in memory. You do not need to worry about it. When the view controller unloads it will unload the UIImageView as well. The only way you could keep a view controller from unloading is keeping a strong reference to it in another view controller. Which sometimes you want eg. parent / child relationship sometimes you don't eg. segue between view controllers. But passing properties between view controllers should be fine. For more info check out View Controller Guide

There are potentially a ton of different ways to solve this question. So, I would take my answer as a starting point and adapt it to what works best for the future of your app and your code style.



来源:https://stackoverflow.com/questions/21443803/storyboard-workflow-for-turn-based-game

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!