Switch from one UIStoryBoard Controller to another UIStoryBoard Controller - swift

Want to navigate between two UIStoryBoard and between different UIViewController. My problem is that when I tap on UIButton the control should transfer to the UIViewController from current UIStoryBoard to another UIStoryBoard.
Any help is appreciated.

You can either Push or Present the new viewController
Using Following code you can push the new view controller to your navigation controller
let yourVC = UIStoryboard(name: StoryBoardName, bundle: nil).instantiateViewController(withIdentifier: ViewConrtollerID) as! YourViewController
self.navigationController?.pushViewController(yourVC, animated: true)

You first need to create reference of the second storyboard in which you want to move from current. For that you need to create reference as shown in below image and set the other story board name in that.
after that you can push the to that storyboard controller using below code.
let vc = UIStoryboard(name:"storyboadnameToPush", bundle: nil).instantiateViewController(withIdentifier:controller storyboardId)
self.navigationController?.pushViewController(vc, animated: true)

Related

Show view controller from main storyboard

I have a case in one of my Swift files which runs the following method:
case .editProfile:
vc = PoiDetailViewController()
self.navigationController?.popViewController(vc,animated: true)
It doesn't seem to work when I run the code.
The view controller is located on the main storyboard and I would like PoiDetailViewController to display when this case is called.
If I understand it correctly, you should be able to achieve what you're looking for by present in your code. Like so:
case .editProfile:
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyBoard.instantiateViewController(withIdentifier: "PoiDetailViewController") // or whatever identifier you have given it
self.present(vc, animated: true, completion: nil)
That should work, however, make sure you set a storyboard ID for your view controller in the identity inspector.
No segues are required.
To set up a storyboard ID click on the View Controller you would like to use (in this case, PoiDetailViewController) and click the identity inspector icon and set a storyboard ID where it asks. I have attached an image so you can see where it needs to go (in the field marked 'Storyboard ID')
Hope that helps.
As per my Understanding you need to pop to specific View Controller if it is in stack and if not then you need to push to that controller
var loginVCFound:Bool = false;
let navigationController : UINavigationController! = self.window!.rootViewController as! UINavigationController;
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil);
let viewControllers: [UIViewController] = navigationController.viewControllers
for aViewController in viewControllers {
if aViewController is LoginVC {// Pass the name of your controller here
loginVCFound = true;
navigationController.popToViewController(aViewController, animated: true)
break;
}
}
if !loginVCFound { // change the identifier and VC with yours
let objLoginVC = mainStoryboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
navigationController.pushViewController(objLoginVC, animated: true)
}

Handling multiple view controllers in swift 4

newbie here... my root view controller has the following code:
func showVC1() {
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let vc1 = storyBoard.instantiateViewController(withIdentifier: "first")
self.present(vc1, animated:true, completion:nil)
}
func showVC2() {
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let vc2 = storyBoard.instantiateViewController(withIdentifier: "second")
self.present(vc2, animated:true, completion:nil)
}
I can call these functions in either order, the first works fine, but the second will give me an error like "Attempt to present on whose view is not in the window hierarchy!"
I think I want to keep all of my code in the root vc that contains these functions. How can I make this work?
I'm also concerned that each time I call these functions I'll be creating new vc instances which will use more memory. Is there a way to keep a reference to these vc's outside of these functions? And will that solve the hierarchy issue?
Yes, second gives an error because you are trying to present two view controller at the same time from root view controller.
You can create lazy references to these view controllers
lazy var firstViewController : FirstViewController = {
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let vc1 = storyBoard.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
return vc1
}()
#IBAction func buttonPressed(_ sender: Any) {
self.present(firstViewController, animated:true, completion:nil)
}
Instead of presenting a new view controller try to push that one into the navigation stack like
self.navigationController.pushViewController(controller, animated: false)
Because if you present anything on your controller it will not continue the navigation. which will lead to crash

How to segue programmatically segue

I've just finished a Swift tutorial which does not use Interface Builder. It is all programmatic. Everything looks great but now I have to segue back to the storyboard, I am lost.
I'd like to segue from the "Login" button designed in the Audible tutorial to the next view controller I created in my storyboard called "DashboardVC".
Here is a link to the tutorial and source code. https://www.letsbuildthatapp.com/course_video?id=382
TIA
As is all from code, you don't have segue's; either you have to push a new controller using pushViewController from NavigationController or instantiate a new ViewController, in this case your 'DashboardVC'.
Like this
let viewController = DashboardVC()
viewController.view.backgroundColor = .blueColor() //example
navigationController?.pushViewController(viewController, animated: true)
Or just presenting the controller using this
let vc = DashboardVC()
present(vc, animated: true, completion: nil)
Using Storyboard, should be like this; the view controller identifier have to be set in the storyboard as well
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier :"DashboardVC") as! DashboardVC
self.present(viewController, animated: true)

Navigation bar dissapears when moving between two storyboards with Swift 3

The project I am working on currently has multiple storyboards. we are programatically moving from the first storyboard to the next using the following code:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "DiscoverViewController") as UIViewController
self.present(vc, animated: true, completion: nil)
the storyboard it is moving to has the Storyboard Entry Point pointed at the Navigation Controller of the view controller that is being instantiated and presented above.
The problem is that when the the page is displayed the navigation bar doesn't appear. It appears on the storyboard view, and before we separated the storyboards we weren't having this issue.
Is there an issue with the way I am going from one storyboard to the other? Do I need to present the navigation controller rather than the view controller?
thanks!
This is because you're presenting the view controller, when instead you probably want to push it onto the navigation stack.
This answer shows what you need to do. Here is the code, adapted for your example:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "DiscoverViewController") as UIViewController
self.navigationController?.pushViewController(vc, animated: true)

how to call existing navigationcontroller in Swift

I have 3 items in my storyboard. 1. viewController (A) connected to 2. Navigation controller and 3. viewController (B) is NOT connected to anything
All 3 items have restoration identifiers set in the storyboard.
viewController (B) is the initial view controller.
I am trying in B to get the navigation controller that A is attached to, but always returns nil:
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyBoard.instantiateViewControllerWithIdentifier("viewControllerA") as! ViewControllerA
print(vc.navigationController?) // always prints nil
why!?
UPDATE#1
I can't declare a UINavigationController like a view controller. I've tried setting navigationcontroller with the id of 'myNavigationController' as storyboardID:
When storyboard, I get this error
let navigationController = storyBoard.instantiateViewControllerWithIdentifier("myNavigationController") as! UINavigationController
print(self.navigationController!) // fatal error: unexpectedly found nil while unwrapping an Optional value
I've also tried setting the id in restoration identifier, It bombed earlier at the instantiating line
#ColdLogic, see what hits I get when I search the entire project for that identifier:
Because you never instantiated the navigation controller, you instantiated view controller A. You would want something like this if you want both the nav controller and the view controller to be setup like they are in the storyboard
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = storyBoard.instantiateViewControllerWithIdentifier("YourNavControllerIdentifier") as! UINavigationController
let vc = navigationController.topViewController as! ViewControllerA
Your code directly instantiates an object of type ViewControllerA. Which, unless you setup logic to do it, does not have a navigation controller by default.
This Worked for me!
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = storyBoard.instantiateViewController(withIdentifier: "HomeNavigationContoller") as! UINavigationController
let viewController = storyBoard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
navigationController.pushViewController(messageVC, animated: true)
self.present(navigationController, animated: true, completion: nil)
Use NavigationController identifier to access the NavigationController and ViewController A is already attached to it, so it will automatically get loaded to NavigationController