Set Rootviewcontroller of Uinavigationcontroller by Method Other Than Initwithrootviewcontroller

Set rootViewController of UINavigationController by method other than initWithRootViewController

You can solve this by calling setViewControllers.

Like this:

UINavigationController *navigationController = [[UINavigationController alloc] initWithNavigationBarClass:[MyNavigationBar class] toolbarClass:[UIToolbar class]];

[navigationController setViewControllers:@[yourRootViewController] animated:NO];

Swift version:

let navigationController = UINavigationController(navigationBarClass: MyNavigationBar.self, toolbarClass: UIToolbar.self)

navigationController.setViewControllers([yourRootViewController], animated: false)

Programmatically set a root viewController

In AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSArray *languages = [userDefaults objectForKey:@"AppleLanguages"];

EPubViewController *epubView = [[EPubViewController alloc] init];
[epubView loadEpub:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"The Chessmen of Mars" ofType:@"epub"]]];
self.navigationController = [UINavigationController alloc]initWithRootViewController:epubView];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}

how to change rootviewcontroller of NavigationController?

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.

How to set self as new window.rootViewController?

The documentation says: The root view controller provides the content view of the window. Assigning a view controller to this property (either programmatically or using Interface Builder) installs the view controller’s view as the content view of the window. The new content view is configured to track the window size, changing as the window size changes. If the window has an existing view hierarchy, the old views are removed before the new ones are installed.

Just as the documentation says: It removes all views in the stack if the rootViewController is exchanged. No matter what's with the controller. So I had to remove self from the stack to assure my view won't be removed. This resulted in following solution:

    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
guard let pageVC = self.onboardingDelegate as? OnboardingPageViewController else { return } // my current stack is in a pageViewController, it also is my delegate
let vc = self // holding myself
pageVC.subViewControllers.removeLast() // removing myself from the list
pageVC.setViewControllers([pageVC.subViewControllers[0]], direction: .forward, animated: false, completion: nil) // remove the current presented VC
appDelegate.window?.rootViewController = vc
vc.onboardingDelegate = nil
appDelegate.window?.makeKeyAndVisible()
}

And it is working fine, just like I wanted.



Related Topics



Leave a reply



Submit