Swift – Instantiating a navigation controller without storyboards in App Delegate

45,246

Solution 1

In Swift 3

Place this code inside didFinishLaunchingWithOptions method in AppDelegate class.

window = UIWindow(frame: UIScreen.main.bounds)
let mainController = MainViewController() as UIViewController
let navigationController = UINavigationController(rootViewController: mainController)
navigationController.navigationBar.isTranslucent = false
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()

Solution 2

In AppDelegate

var window: UIWindow?
var navController: UINavigationController?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    navController = UINavigationController()
    var viewController: ViewController = ViewController()
    self.navController!.pushViewController(viewController, animated: false)

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

    self.window!.rootViewController = navController

    self.window!.backgroundColor = UIColor.whiteColor()

    self.window!.makeKeyAndVisible()

    return true
}

In ViewController

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    self.title = "FirstVC"

    var startFinishButton = UIButton.buttonWithType(UIButtonType.System) as! UIButton
    startFinishButton.frame = CGRectMake(100, 100, 100, 50)
    startFinishButton.backgroundColor = UIColor.greenColor()
    startFinishButton.setTitle("Test Button", forState: UIControlState.Normal)
    startFinishButton.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)

    self.view.addSubview(startFinishButton)
}

func buttonAction(sender:UIButton!)
{
    println("Button tapped")
    let vc = SecondViewController()
    self.navigationController?.pushViewController(vc, animated: true)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}
Share:
45,246
Zack Shapiro
Author by

Zack Shapiro

Updated on April 12, 2020

Comments

  • Zack Shapiro
    Zack Shapiro about 4 years

    I'm rebuilding an app without storyboards and the part of it that I'm having the most trouble with is navigating view-to-view programatically. Few things are written out there which don't use storyboards, so finding an answer for this has been tough.

    My problem is pretty simple. I have my ViewController and my SecondViewController and I want to push from the former to the latter.

    In AppDelegate:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
    
        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        window?.backgroundColor = UIColor.whiteColor()
        window?.rootViewController = ViewController()
        window?.makeKeyAndVisible()
    
        return true
    }
    

    Then in ViewController.swift:

    class ViewController: UIViewController, AVAudioPlayerDelegate, UITextFieldDelegate {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            startFinishButton.setTitle("Begin", forState: .Normal)
            startFinishButton.addTarget(self, action: "moveToSecondViewController", forControlEvents: .TouchUpInside)
            view.addSubview <*> startFinishButton
        }
    
        func moveToSecondViewController(sender: UIButton) {
            let vc = SecondViewController()
            println(self.navigationController) // returns nil
            self.navigationController?.pushViewController(vc, animated: true)
        }
    }
    

    Printing self.navigationController returns nil. I've tried doing:

    var navController = UINavigationController() when the ViewController class is created (but outside of ViewDidLoad, right under the class declaration) and done the push using the navController var but that hasn't worked.

    I'm thinking maybe the solution is to create a navigation controller in App Delegate that the whole app would use, I guess as a global variable?

    My hope is that this post can serve many others who are new to Swift and want to remove storyboards from their app.

    Thanks for taking a look and for your help.