Reputation: 3408
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
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
Reputation: 11
- (void) changeRootViewControllerOFNavigationControlllerAtRuntime:(UIViewController *) viewController {
UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:viewController];
[UIApplication sharedApplication].delegate.window.rootViewController=navController;
}
Upvotes: 1
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
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
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