0

I'm working on an existing application which uses the storyboard but I want to continue development without using the storyboard at all, or nib files.

The existing left menu is a UITableView which is not the root controller and does not have a navigation controller associated with it. I have created a UINavigationController in the app delegate and want to use this navigation controller to push a new controller. I am able to present a view controller but I want to use push in order to conform with the current UIX.

In the following code nothing happens because navigationController? returns nil.

Here is my new code in the app delegate.

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

var navController: UINavigationController?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    navController = UINavigationController()

    self.window = UIWindow(frame: UIScreen.main.bounds)

    self.window!.rootViewController = navController

    self.window!.backgroundColor = .red

    self.window!.makeKeyAndVisible()

    let menuViewController = SideMenuViewController()

    menuViewController.navController = navController

Then in my side menu controller:

import UIKit

class SideMenuViewController: UIViewController {

var navController: UINavigationController?

.......

   let myViewController = myViewController()

   self.navigationController?.pushViewController(myViewController, animated: true )

1 Answer 1

1

From the UIViewController documentation:

var navigation​Controller:​ UINavigation​Controller?
The nearest ancestor in the view controller hierarchy that is a navigation controller.

Which means when you call self.navigationController in a view controller you get the (nearest) navigation controller that self is embedded in. Apparently your menu controller is not embedded in the navigation controller hierarchy. Using your app delegate's navController member is one way to make this work. Then you can say in your menu view controller:

func menuItemFooSelected()
{
    let navController = (UIApplication.shared.delegate as! AppDelegate).navController
    let myViewController = myViewController()
    navController?.pushViewController(myViewController, animated: true)
}

Alternatively (and probably preferably), when you set up your initial structure in your app delegate, inject the navigation controller into the side menu controller:

class MenuViewController: UIViewController
{
    var navController: UINavigationController?
    ...

    func menuItemFooSelected()
    {
        let myViewController = myViewController()
        self.navController?.pushViewController(myViewController, animated: true)
    }
}

In application(_:didFinishLaunchingWithOptions:)

...
let menuViewController = MenuViewController(...)
menuViewController.navController = navController
Sign up to request clarification or add additional context in comments.

8 Comments

I had a typo but it did nothing at all. Do the lines let navController... go in the app delegate? I don't understand what goes in the dotted lines and I will need to use this for many view controllers.
The dots just stand for how you create your menu view controller because I don't know what initializer you use. The important part is to add the navController property to your menu view controller and set this to the navigation controller that you create in your app delegate. You only need to do this once for the menu view controller and then you can push any view controller you like from within that menu view controller.
I updated the answer to (hopefully) clarify what goes where.
I updated my question to show what I believe you posted but it still fails with no error.
I just see that you are not using one of the designated initializers of UINavigationController, e.g. init(root​View​Controller:​).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.