94

I'd like to navigate from one view controller to another. How can I convert the following Objective-C code into Swift?

UIViewController *viewController = [[self storyboard] instantiateViewControllerWithIdentifier:@"Identifier"];
UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:viewController];
[self.navigationController pushViewController:navi animated:YES];
1

16 Answers 16

233

Create a swift file (SecondViewController.swift) for the second view controller and in the appropriate function type this:

let secondViewController = self.storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as SecondViewController
self.navigationController.pushViewController(secondViewController, animated: true)


Swift 2+

let mapViewControllerObj = self.storyboard?.instantiateViewControllerWithIdentifier("MapViewControllerIdentifier") as? MapViewController
self.navigationController?.pushViewController(mapViewControllerObj!, animated: true)

Swift 4

let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "IKDetailVC") as? IKDetailVC
self.navigationController?.pushViewController(vc!, animated: true)
Sign up to request clarification or add additional context in comments.

10 Comments

@audrey,Hi, how to set navigationController?
@Sanjivani, Hi your view controller can be created with Storyboard and assign your firstViewController as rootViewController.Your navigation Controller (swift) class will look like this: import UIKit class SwiftNavigationController: UINavigationController { init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) // Custom initialization }`` override func viewDidLoad() { super.viewDidLoad() }
I also had same problem, I was stuck at how to navigate from one ViewController to another. When I tried this code, I am getting this error: unexpectedly found nil while unwrapping an Optional value at second line of your code. Please help
I am having an issue with the animated: parameter like so: "Cannot convert the expression's type '$T7??' to type 'BooleanLiteralConvertible'".
You need to make sure your controllers are embedded in a NavigationController for this to work, otherwise you will get errors.
|
37

In my experience navigationController was nil so I changed my code to this:

let next = self.storyboard?.instantiateViewControllerWithIdentifier("DashboardController") as! DashboardController
self.presentViewController(next, animated: true, completion: nil)

Don't forget to set ViewController StoryBoard Id in StoryBoard -> identity inspector

1 Comment

This is because your view controller wasn't ebbed in a Navigation View Controller.
19

If you don't want the back button to appear (which was my case, because I wanted to present after a user logged in) here is how to set the root of the nav controller:

let vc = self.storyboard?.instantiateViewControllerWithIdentifier("YourViewController") as! YourViewController
        let navigationController = UINavigationController(rootViewController: vc)
        self.presentViewController(navigationController, animated: true, completion: nil)

Comments

17

SWIFT 3.01

let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "Conversation_VC") as! Conversation_VC
self.navigationController?.pushViewController(secondViewController, animated: true)

Comments

8

In swift 4.0

var viewController: UIViewController? = storyboard().instantiateViewController(withIdentifier: "Identifier")
var navi = UINavigationController(rootViewController: viewController!)
navigationController?.pushViewController(navi, animated: true)

Comments

6

In Swift 4.1 and Xcode 10

Here AddFileViewController is second view controller.

Storyboard id is AFVC

let next = self.storyboard?.instantiateViewController(withIdentifier: "AFVC") as! AddFileViewController
self.present(next, animated: true, completion: nil)

//OR

//If your VC is DashboardViewController
let dashboard = self.storyboard?.instantiateViewController(withIdentifier: "DBVC") as! DashboardViewController
self.navigationController?.pushViewController(dashboard, animated: true)

If required use thread.

Ex:

DispatchQueue.main.async { 
    let next = self.storyboard?.instantiateViewController(withIdentifier: "AFVC") as! AddFileViewController
    self.present(next, animated: true, completion: nil) 
}

If you want move after some time.

EX:

//To call or execute function after some time(After 5 sec)
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
    let next = self.storyboard?.instantiateViewController(withIdentifier: "AFVC") as! AddFileViewController
    self.present(next, animated: true, completion: nil) 
} 

Comments

6
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let home = storyBoard.instantiateViewController(withIdentifier: "HOMEVC") as! HOMEVC
navigationController?.pushViewController(home, animated: true);

1 Comment

i think it's not Swift or Objc syntax
3

Swift 3

let secondviewController:UIViewController =  self.storyboard?.instantiateViewController(withIdentifier: "StoryboardIdOfsecondviewController") as? SecondViewController

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

Comments

3

In swift 3

let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "NextViewController") as! NextViewController        
self.navigationController?.pushViewController(nextVC, animated: true)

Comments

3

For Swift 4 & 5 Users can use this way

Swift 5

 let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
 let vc = storyBoard.instantiateViewController(withIdentifier: "YourViewController") as! YourViewController
 self.navigationController?.pushViewController(vc, animated: true)

Swift 4

let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "YourViewController") as? YourViewController 
self.navigationController?.pushViewController(vc!, animated: true)

Comments

2
let objViewController = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.navigationController?.pushViewController(objViewController, animated: true)

2 Comments

Could you please explain shortly what your code does, why it solves the problem and how it's different from all the other answers.
here i am using storyboard id as identifier . Via the reference (objViewController) push the control to the View Controller class
2

Swift 5

Use Segue to perform navigation from one View Controller to another View Controller:

performSegue(withIdentifier: "idView", sender: self)

This works on Xcode 10.2.

1 Comment

type of segue ?
2

Better practices Swift 5.0

More reusable and readable

Create a protocol

protocol Storyboarded { }

Now create an extension of the protocol

extension Storyboarded where Self: UIViewController {
    
    static func instantiateFromMain() -> Self {
        let storyboardIdentifier = String(describing: self)
        // `Main` can be your stroyboard name.
        let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        
        guard let vc = storyboard.instantiateViewController(withIdentifier: storyboardIdentifier) as? Self else {
            fatalError("No storyboard with this identifier ")
        }
        return vc
    }
}
// Make a ViewController extension to use on all of your ViewControllers
extension UIViewController: Storyboarded {}

How to use

  let vc = MyViewController.instantiateFromMain()
  //here you can pass any data to the next view controller. for example we have a variable with name `myString` in our next view contoller and we want to pass the data my `self viewController`
  vc.myString = "This string passed by MyViewController"
  self.navigationController?.pushViewController(vc, animated: true)

Note:- You need to give the same identifier on the storyboard as your UIViewController class has. Check the example below

enter image description here

3 Comments

how to call this if it is extension of Storyboarded
@Pramod Shukla Confirm protocol Storyboarded on your ViewController and you will be able to use it. Or make a view controller extension something like this extension UIViewController: Storyboarded {}
@pramod-shukla I also updated my answer you can use it accordingly
1

Swift 4

You can switch the screen by pushing navigation controller first of all you have to set the navigation controller with UIViewController

let vc = self.storyboard?.instantiateViewController(withIdentifier: "YourStoryboardID") as! swiftClassName

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

Comments

1

In AppDelegate you can write like this...

var window: UIWindow?

fileprivate let navigationCtrl = UINavigationController()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    self.createWindow()

    self.showLoginVC()

    return true
}

func createWindow() {
    let screenSize = UIScreen.main.bounds
    self.window = UIWindow(frame: screenSize)
    self.window?.backgroundColor = UIColor.white
    self.window?.makeKeyAndVisible()
    self.window?.rootViewController = navigationCtrl
}

func showLoginVC() {
    let storyboardBundle = Bundle.main
    // let storyboardBundle = Bundle(for: ClassName.self) // if you are not using main application, means may be you are crating a framework or library you can use this statement instead
    let storyboard = UIStoryboard(name: "LoginVC", bundle: storyboardBundle)
    let loginVC = storyboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
    navigationCtrl.pushViewController(loginVC, animated: false)
}

Comments

-1

Update for Swift 5:

    let next = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController

    self.present(next, animated: true, completion: nil)

Don't forget to update the Storyboard ID for both View Controllers!

1 Comment

you know, Swift is on version 5.4.

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.