How to switch view controllers in swift? - ios

I'm trying to switch from one UIViewController to another using code. Right now I have,
self.presentViewController(ResultViewController(), animated: true, completion: nil)
All this is doing is taking me to a black screen instead of the ResultViewController. Any suggestions?

With Storyboard. Create a swift file (SecondViewController.swift) for the second view controller
and in the appropriate function type this:
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController") as! secondViewController
self.navigationController.pushViewController(secondViewController, animated: true)
Without storyboard
let secondViewController = ViewController(nibNameOrNil: NibName, bundleOrNil: nil)
self.presentViewController(secondViewController, animated: true, completion: nil)

You can try this one
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let resultViewController = storyBoard.instantiateViewControllerWithIdentifier("ResultView") as ResultViewController
self.presentViewController(resultViewController, animated:true, completion:nil)
Make sure you set your view controller identifier.

Swift 3
To present a controller modally
let vc = self.storyboard!.instantiateWithIdentifier("SecondViewController")
self.present(vc, animate: true, completion: nil)
To show a controller
self.show(vc, sender: self)

Try this:
let vc = ViewController(nibNameOrNil: yourNibName, bundleOrNil: nil)
self.presentViewController(vc, animated: true, completion: nil)
Hope this helps.. :)

The easiest way to do this would be to create a segue by right clicking on the view you are starting on and dragging the blue line to the result view controller the hit the show segue option. Then set the identifier of the segue to "segue". Now add this code wherever you would like in your view controller:
self.performSegueWithIdentifier("segue", sender: nil)
this will trigger the segue that will go to your resultViewController

The easiest way to switch between screens in iOS is. Add a button on the current screen. Then press control and drag the button to the target screen. Then select push. And when you will tap the button the screen will be switched to the target screen.
Make sure you are using a UINavigationViewController.
Source: ios UINavigationController Tutorial.

Shaba's answer is a good start but requires the following so that you
can control the segue from within your view controller:
override func shouldPerformSegue(withIdentifier identifier: String,
sender: Any?) -> Bool {
// your code here
// return true to execute the segue
// return false to cause the segue to gracefully fail }
Source

vc = YourViewController()
UIApplication.shared.keyWindow?.rootViewController = vc
Or
vc = YourViewController()
UIApplication.shared.keyWindow?.rootViewController = UINavigationController(rootViewController: vc) //If you want to add navigation functionality to that VC

Related

push to the nextViewcontroller from popUp is not working

I have a UIViewcontroller that presents a popUpView with two buttons, cancel and continue respectively.. but the problem is that when I press the continue button, UINavigationController is not pushing to the next UIViewcontroller.. .
-- onNextButtonTapped:
#IBAction func onOkayButtonClicked(_ sender: UIButton) {
self.dismiss(animated: true, completion: {
let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "nextVC") as! NextViewController
// let nextVCNav = UINavigationController(rootViewController: nextVC)
//self.navigationController?.pushViewController(nextVCNav, animated: true)
self.navigationController?.pushViewController(nextVC, animated: true)
})
}
Did miss something?
This seems like a controller chain issue. As from what I understand you must have presented the popup modally and by doing that you have moved out of the UINavigationController stack. So pushing a view from popupview controller is not an option. You can:
Create a protocol, (or block implementation) that inform viewcontroller which presented popup, that particular button was clicked (something similar to UIAlertController)
Make a popup as a view inside view controller and show and hide that with animation. That was you can add the action of the button of this popup to your view controller.
I think the UINavigationController is not in hierarchy.
Try this
let nav = UINavigationController(rootViewController: self)
UIApplication.shared.keyWindow?.rootViewController = nav
nav.pushViewController(nextVC, animated: true)

Swift - popViewController after Dismiss

I'm trying to dismiss viewcontroller presented as modal("Present Modally") and then popViewController in navigationController. Here is my storyboard, I want to go from QRScanner VC to Monitoring VC.
Here is how I'm presenting QRScanner VC in Add Device VC:
let storyboard = UIStoryboard(name: StoryboardIDs.MainStoryboard, bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: VCIDs.QRDeviceScannerVC) as! QRDeviceScannerVC
controller.deviceName = deviceNameTxt.text
present(controller, animated: false, completion: nil)
Here is how I'm trying to go back to MonitoringVC:
self?.navigationController?.popViewController(animated:true)?.navigationController?.popViewController(animated: false)
Also tried:
self?.dismiss(animated: true, completion: {
self?.presentingVC?.navigationController?.popViewController(animated: false)
})
It always goes to the Add Device VC instead of Monitoring VC
Use an unwind segue, with the unwind target method located in the Monitoring VC. All the right stuff will just happen as if by magic.
You can try with
self?.dismiss(animated: false, completion:nil)
self?.presentingVC?.navigationController?.popViewController(animated: true)
Just check if you have reference to the navigation controller

How to switch to other view controller programmatically in Swift 4?

I need to switch page(other view controller) using a button.
I have two controllers (viewController to HomeViewController)
I have a button created in viewController:
let acceptButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Accept", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
//button.sendAction(Selector(buttonAction), to: HomeViewController(), for: .touchUpInside)
return button
}()
and I have set a function and used a print statement to test the function:
#objc func buttonAction(sender: UIButton){
print("button pressed")
}
I executed the program and when I press the button it prints out "button pressed"
Then I added the following into the function:
let HomeViewController = ViewController(nibName: ViewController, bundle: nil)
self.presentViewController(HomeViewController, animated: true, completion: nil)
As a result, it does not switch to other viewController(HomeViewController).
Any idea on how should I make it works? Thank you
There are couple of ways to switch to another ViewController.
Navigation
Present
If you have created the controllers in storyboard then you have to first get the instance of storyboard in case of multiple storyboards.
In case of multiple storyboard you need to mention the name of the storyboard.
let sampleStoryBoard : UIStoryboard = UIStoryboard(name: "UserBoard", bundle:nil)
Then get the instance of the view controller you wish to switch.
* Make sure you set the correct Identifier in ViewController.
let homeView = sampleStoryBoard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
if you wish to present the view controller:
self.present(homeView, animated: true, completion: nil)
if you wish to push the view controller:
self.navigationController?.pushViewController(homeView, animated: true)
if you want to Switch to another Controller which you created as Xib
let homeView = HomeViewController(nibName: "HomeViewController", bundle: nil)
If you want to push:
self.navigationController?.pushViewController(homeView, animated: true)
Present the Controller:
present(homeView, animated: true, completion: nil)
Other ways to Switch between Controllers.
Wiring up the Segues
Ctrl+Drag from the “View Controller” button, to somewhere in the second View Controller(HomeViewController). It can be anywhere in the main box of the second view controller. When you release, it will show you a box like the one below.
in this you don't need any code to switch, it will switch on click of a button.
or you can CTLR + Drag from View controller to other controller to create segue and write below code on click of button action and switch to another view controller.
performSegue(withIdentifier: "mySegueID", sender: nil)
make sure you set the correct identifier of segue.
Details of different segues
Show — When the View Controllers are in a UINavigationController, this pushes the next View Controller onto the navigation stack. This allows the user to click the back button to return to the previous screen through the back button on the top left of the Navigation Bar.
Present modally — This presents the next view controller in a modal fashion over the current View Controller. This one doesn’t need to be part of a UINavigationController or a UISplitViewController. It just shows the destination View Controller in front of the previous one. This is usually used when the user has to either Finish or Cancel .
Custom — Exactly what it sounds like. You can make your own segue style and transitions and use it here.
Switch to another viewController programmatically in Swift 4 -
Navigation process
first, you need to embed your view with Navigation Controller like -
For Navigation programmatically you can use below code -
But this code work with if you working with StoryBoard in your project.
First, you need to set view identifier in storyBoard
Push with StoryBoard
let homeView = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
self.navigationController?.pushViewController(homeView, animated: true)
Present with StoryBoard
let homeView = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
present(homeView, animated: true, completion: nil)
Push with XIB
let homeView = HomeViewController(nibName: "HomeViewController", bundle: nil)
self.navigationController?.pushViewController(homeView, animated: true)
Present with XIB
let homeView = HomeViewController(nibName: "HomeViewController", bundle: nil)
present(homeView, animated: true, completion: nil)
For avoiding any crashes you can also try this code -
guard let homeView = HomeViewController(nibName: "HomeViewController", bundle: nil) else {
print("Controller not available")
return
}
self.navigationController?.pushViewController(homeView, animated: true)
you can switch to a Controller in two ways
Present and Dismiss
Navigation Controller
-> First Method is simple
just need to write two lines as :
In case Controller in Another storyboard file
let newStoryBoard : UIStoryboard = UIStoryboard(name: "UserBoard", bundle:nil)
let VC = newStoryBoard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
self.present(VC, animated: true, completion: nil)
Or if in same storyboard
let VC = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
self.present(VC, animated: true, completion: nil)
-> Second using navigation Controller
Just make use of a navigation controller and then push or pop controllers in navigation stack
let VC = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
self.navigationController?.pushViewController(VC, animated: true)
In your case You are providing bundle as Nil which is wrong
let HomeViewController = ViewController(nibName: ViewController, bundle: nil)
///Need to Provide Bundle detail
let HomeViewController = ViewController(nibName: ViewController, bundle: Bundle.main)
let HomeViewController = ViewController(nibName: "ViewController", bundle: Bundle.main)
self.presentViewController(HomeViewController, animated: true, completion: nil)

How to go back to the initial ViewController the right way?

I have a few view controllers with navigation bar and tab bar. Then I have an initial view controller with no navigation bar and tab bar. I want to go back to the initial view controller with no other view controllers in stack. Here's what I do:
// Head back to Initial View Controller.
let initialViewController = self.storyboard!.instantiateViewController(withIdentifier: "Initial")
UIApplication.shared.keyWindow?.rootViewController = initialViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = initialViewController
This works perfectly. But then it doesn't move to another view controller from the initial view controller again. For example:
#IBAction func loginButton(_ sender: Any) {
print("Login Button Tapped.")
let storyboard = UIStoryboard(name: "SignInViewController", bundle: nil)
let signInViewController = storyboard.instantiateViewController(withIdentifier: "SignInViewController") as! SignInViewController
self.navigationController?.show(signInViewController, sender: nil)
}
Here, the print statement is run, but self.navigationController.show won't. How do all this work? And what's the right approach to accomplish this?
EDIT:
To avoid any confusion, here's my storyboard. The left most viewcontroller (pink screen) is the initial view controller I want to go back to. The right most on the same level is the view where I want to go back from.
It doesn't move to another view controller, because you are setting a simple view controller in your rootViewController.
What you need is:
let initialViewController = self.storyboard!.instantiateViewController(withIdentifier: "Initial")
let navController = UINavigationController.init(rootViewController: initialViewController)
UIApplication.shared.keyWindow?.rootViewController?.present(navController, animated: true, completion: nil)
This will create a navigationviewcontroller, so when on "Initial" you should be able to perform push, present actions of another view controllers.
From your initial view controller, you need to instantiate your navigation stack and present it modally. Then, when you want to get back to your pre-navigation initial VC, just call dismiss(animated:,completion:), which will dismiss your entire navigation stack and return you to the initial view controller.
self.navigationController.popToRootViewController(animated:) is what you're looking for.
https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621855-poptorootviewcontroller
EDIT
Try dismissing the navigationController after calling popToRoot.
self.navigationController.dismiss(animated: true, completion: nil)
EDIT
Try the following:
#IBAction func loginButton(_ sender: Any) {
print("Login Button Tapped.")
let storyboard = UIStoryboard(name: "SignInViewController", bundle: nil)
let signInViewController = storyboard.instantiateViewController(withIdentifier: "SignInViewController") as! SignInViewController
present(signInViewController, animated: true, completion: nil)
//self.navigationController?.show(signInViewController, sender: nil)
}
Then to dismiss the signInViewController call self?.navigationController.dismiss(animated:true, completion:nil) from inside the signInViewController.

Swift Xcode Button not showing next view

I'm trying to code a button that simply switches to the next view. So I embedded the first ViewController into a navigation controller then I dragged in another view controller, created a new class name ViewController2 and associated that class with the second ViewController and came the second view controller a storyboard id:"view2". Then in the Button's function I added this code:
#IBAction func newGamePressed(sender: AnyObject) {
let view2 = self.storyboard?.instantiateViewControllerWithIdentifier("view2") as
ViewController2
self.navigationController?.pushViewController(view2, animated: true)
}
However when i click on the button, literally nothing happens!!! what am i doing wrong???
#IBAction func newGamePressed(sender: AnyObject) {
let VC1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("view2")
let navController = UINavigationController(rootViewController: VC1)
self.presentViewController(navController, animated:true, completion: nil)
}
Just try with this code.

Resources