Search code examples
iosuiviewcontrolleruinavigationcontrollerpushviewcontroller

IOS. Navigation Controller. Reuse ViewControllers


Here is my problem. I have a view based application. I added a NavigationController to the AppDelegate as follows.

UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:_viewController];    
navigationController = [nvc retain];
[nvc retain];     
[self.window addSubview:navigationController.view];

This code I got from internet. I don't know if it is correct.

In all the viewControllers I am doing the following to push a new view.

UIViewController *newViewController = [[NewViewController alloc] init];
[self.navigationController pushViewController:newViewController animated:TRUE];
  1. I don't know why self.navigationController does not return nil in the pushed views. Is it using AppDelegate navigation controller somehow?

  2. If I want to reuse some view controllers. I mean not alloc init every time that I want to call the view controller. How can I do that? Store a reference in the AppDelegate? Any other solution?

  3. I have a complicated navigation. i.e. A, B, C are view controllers. A calls B. B calls C. C calls A. If I keep calling I am creating a new view controller each time. How can I reuse those view controllers (or pop and release the view from the stack when calling a new one)?

Thanks.


Solution

  • 1) navigationController is a property of UIViewController. If the view controller is part of a navigation controller hierarchy then it will be set.

    2) You'll have to manage this yourself. Storing a reference in the object that pushes that view controller would be the usual way to achieve this. So if A pushes B then A stores a reference to B, etc.

    3) There's no way to get UINavigationController to do this for you. From what you're trying to do I assume you're coming from an Android background? Android has specific ways to do just that, but in iOS you'd have to code it yourself. You could do this by looking at UINavigationControllerDelegate and its navigationController:didShowViewController:animated: method. You could see when a view controller is pushed and if it's already in the stack then update the navigation stack (i.e. the viewControllers property of UINavigationController) to remove it from where it was. But that might get quite confusing for the user.