Nuzhat Zari
Nuzhat Zari

Reputation: 3408

how to change rootviewcontroller of NavigationController?

I have navigationController which is presented as modalview and whose rootviewcontroller is say FirstViewController.At some point I want to change rootviewcontroller of navigationController to SecondViewController.What I did is

[self.navigationController initWithRootViewController:SecondViewController];

I am not sure what I did is correct and whether or not FirstViewController got released?Please anyone know what is the correct way of doing this?

Thanks in advance!

Upvotes: 24

Views: 33271

Answers (5)

Vyacheslav
Vyacheslav

Reputation: 27211

Swift 3

fileprivate func changeRootVC() {
        if let newVC  = self.storyboard?.instantiateViewController(withIdentifier: "MyStoryboardID"), let nc = self.navigationController {
            nc.setViewControllers([newVC], animated: true)
        }

    }

Upvotes: 1

Abhilash Khunte
Abhilash Khunte

Reputation: 11

- (void) changeRootViewControllerOFNavigationControlllerAtRuntime:(UIViewController *) viewController {

     UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:viewController];
     [UIApplication sharedApplication].delegate.window.rootViewController=navController; 
}     

Upvotes: 1

user1072975
user1072975

Reputation: 33

You need to make custom UINavigationController

@interface mySwitchRootViewNavigationController()

@property (nonatomic, retain) myFirstViewController * FirstViewController;
@property (nonatomic, retain) mySecondViewController * SecondViewController;

@end

- (void)viewDidLoad
{
  [super viewDidLoad];
  self.FirstViewController = [[myFirstViewController alloc] init];
  self.SecondViewController = [[mySecondViewController alloc] init];
}

-(void) setRootViewControllerWithID:(int) viewControllerID
{
  if (viewControllerID == 1) {
    self.viewControllers = [NSArray arrayWithObject:self.SecondViewController];
  } else
  {
    self.viewControllers = [NSArray arrayWithObject:self.FirstViewController];
  }
}

-(void)viewWillAppear:(BOOL)animated
{
  [self setRootViewControllerWithID:intVar];
  [super viewWillAppear:animated];
}

initialization

mySwitchRootViewNavigationController * switchView = [mySwitchRootViewNavigationController alloc] init];

Upvotes: 0

Jacco
Jacco

Reputation: 493

This is not the correct way, calling init on an already initialized object rarely (i think never) is.

The way i solved this issue, is to create a subclass of UINavigationController.

In this subclass, i overwrite the initwithrootviewcontroller:

- (id) initWithRootViewController:(UIViewController *)rootViewController
{
    UIViewController *fakeController = [[[UIViewController alloc] init] autorelease];

    self = [super initWithRootViewController:fakeController];
    if(self)
    {
        self.fakeRootViewController = fakeController;
        rootViewController.navigationItem.hidesBackButton = YES;

        [self pushViewController:rootViewController animated:NO];
    }
    return self;
}

The fakeRootViewController actually does nothing, it's a workaround for iOS not having a possibility to set the rootviewcontroller.

In another function (setRootViewController: aViewController) you hide the backbutton of the new 'rootviewcontroller' so the user never sees that there is a fake rootviewcontroller. and then push it above the fakerootviewcontroller

The poptorootviewcontroller should be overwritten to make sure it always pops to index 1 of the stack, not index 0.

The getter of viewcontrollers should be changed so it returns an array without the fakerootviewcontroller (removeobjectatindex: 0)

Hope this helps!

Upvotes: 0

Costique
Costique

Reputation: 23722

Do either

[firstViewController.navigationController setViewControllers: [NSArray arrayWithObject: secondViewController] 
                                                    animated: YES];

or

firstViewController.navigationController.viewControllers = [NSArray arrayWithObject: secondViewController];

where firstViewController is an instance of FirstViewController and secondViewController is an instance of SecondViewController classes, respectively. The latter variant is a shortcut for setViewControllers:animated: without animation.

Upvotes: 47

Related Questions