DanielGibbs
DanielGibbs

Reputation: 10191

Switching to an arbitrary view using `UINavigationController`

I have an iPhone app that uses a UINavigationController that is created as so:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Create navigation controller and initialize it with the menu view controller.
    navigationController = [[UINavigationController alloc] initWithRootViewController:[[MenuViewController alloc] init]];
    navigationController.navigationBar.hidden = YES;
    navigationController.toolbar.hidden = YES;

    // Create main window and initialize it with navigation view controller.
    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [window setRootViewController:navigationController];
    [window makeKeyAndVisible];
    return YES;
}

From there things usually happen in a sequence similar to the following:

  1. Push SelectDifficultyViewController
  2. Push GameViewController
  3. Push GameOverViewController
  4. Pop to root (MenuViewController)

Instead of popping to the root in step 4, how would I go about switching to a new instance of GameViewController.

I currently have the following but it just returns me to the root:

[self.navigationController popToRootViewControllerAnimated:NO];
[self.navigationController pushViewController:[[GameViewController alloc] initWithStuff:stuff] animated:NO];

Upvotes: 1

Views: 96

Answers (2)

DanielGibbs
DanielGibbs

Reputation: 10191

mehinger's answer solved my problem, but I wanted to make it easier to use, so I made the following category.

UINavigationController+PopAndPush.h

@interface UINavigationController(PopAndPush)

- (void)popAndPushToViewController:(UIViewController *)controller animated:(BOOL)animated;
- (void)popAndPushToViewController:(UIViewController *)controller withCustomTransition:(CustomViewAnimationTransition)transition;

@end

UINavigationController+PopAndPush.m

#import "UINavigationController+PopAndPush.h"

@implementation UINavigationController(PopAndPush)

- (void)popAndPushToViewController:(UIViewController *)controller animated:(BOOL)animated {
    [self popToRootViewControllerAnimated:NO];
    [self pushViewController:controller animated:animated];
}

- (void)popAndPushToViewController:(UIViewController *)controller withCustomTransition:(CustomViewAnimationTransition)transition {
    [self popToRootViewControllerAnimated:NO];
    [self pushViewController:controller withCustomTransition:transition subtype:nil];
}

@end

Upvotes: 0

angerboy
angerboy

Reputation: 495

As it turns out, the line [self.navigationController popToRootViewControllerAnimated:NO] will result in self.navigationController being nil, which is why the subsequent push to the navigationController does nothing. To fix this, store a local copy of the navigation controller and use that to push after popping to root. Credit for this answer comes from here:

UINavigationController popToRootViewController, and then immediately push a new view

Upvotes: 2

Related Questions