Moving between ViewControllers without a storyboard or NavController

Hi,

There are many tutorials out there explaining how to program UI / Auto Layout without using a StoryBoard, which is great & I have learned a lot. But…

How do you switch between two ViewControllers without using a model or navigation controller? Basically, I would like to push a button on the first view controller that would push the second ViewController in a non-model view? Do I have to use a navigation controller?

Thanks,

Hi @pdl5000, could you share code with us in regards to what you have tried?

Best,
Gina

Hi Gina,

Sure.

From AppDelegate:
var window: UIWindow?

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

    self.window = UIWindow(frame: UIScreen.main.bounds)
    let mainView = MainViewController()
    let navController = UINavigationController()
   
    self.window?.rootViewController = mainView
    navController.popToRootViewController(animated: true)
    self.window?.makeKeyAndVisible()
    return true
}

From the first ViewController:

@objc func button_clicked() {

    dismiss(animated: true, completion: nil)
    let ac = ActionViewController()
    self.present(ac, animated: true, completion: nil)

}

Thanks,
Paul

Hi @pdl5000

In the steps of your code you:

1.- Create a MainViewController

2.- Create a UINavigationController

3 .- Set mainView as the rootViewController for window

4.- Tell navController to dismiss all pushed controllers and go back to root controller

At this point window will display mainView and you’ll never see the navController so all code related to it is useless.

If you want to push a UIViewController that can only be achieved by a UINavigationController, pushed from right to left displaying automatically a back button in the navigation bar

  navigationController.pushViewController(viewController, animated: true)

While any UIViewController can present any UIViewController modally, user must handle dismiss events manually

  // Present      
  mainViewController.present(detailsViewController, animated: true, completion: nil)
  // Dismiss
  viewController.dismiss(animated: true, completion: nil)

This is an example of how to start your app with a UINavigationController:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  self.window = UIWindow(frame: UIScreen.main.bounds)
  // Create a MainViewController
  let mainView = MainViewController()
  // Create a UINavigationController and set the mainView as rootViewController
  let navController = UINavigationController(rootViewController: mainView)
  // Set navController as the rootViewController for window
  self.window?.rootViewController = navController
  self.window?.makeKeyAndVisible()
  return true
}

Hope it helps,
Good Luck :]

1 Like

Jecht83,

Thanks for your response.
The ‘self.present(ac, animated: true, completion: nil)’ then dismiss method only open a model / dismiss the view.

How do I access the navController from the MainViewController to present the second VC? Or not use a navigationController at all and just push a second VC while dismissing the first VC?

Thanks again,

Hey @pdl5000

If you follow the sample code that I shared with you then you’ll be able to start with a NavigationController that contains a viewController as a child, so it’s a good start :+1:.

After that if you want to access the navigationController you will call the optional:

self.navigationController?

This optional variable can be called from any UIViewController, if your viewController have a navigationController as parent then the variable won’t be nil and if your viewController do not have a navigationController as parent then it will be nil

If you followed the sample code then you can push a new viewController with:

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

If you want to double check that the navigationController exists before pushing then you can unwrap the optional with:

if let navigationController = self.navigationController? {
  navigationController.pushViewController(secondViewController, animated: true)
}

With this approach the app won’t crash if the navigationController do not exists

Hope it helps,
Good Luck :]

jecht83,

Thank you, with your help I got it to work.

Thank you for helping @jecht83! Your explanations were well explained. And @pdl5000, glad you were able to get it to work.

@gdelarosa Glad to help :cowboy_hat_face:

Hi @jecht83,
That is a good example, however just wanted to point out one small thing, starting from iOS13, Apple have changed the way the app starts with the use of SceneDelegates, in this case, it might not affect things, however if you are also trying to capture entry points into the application, it might have to be in the SceneDelegates not the AppDelegate.

cheers,

This topic was automatically closed after 166 days. New replies are no longer allowed.