How to show a ViewController (not modally) within a UITabViewController - ios

I want to show a ViewController within a UITabController but not display it modally. In the app, there's a home screen with a bunch of buttons that segue to other ViewControllers. The other view controllers are embedded in a navigation controller. I now have a need to show one of the ViewControllers from a TodayExtension. In my app delegate I have this but it presents the RequestorViewContoller modally without the tab structure or the navigation control.
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let requestor = mainStoryboard.instantiateViewController(withIdentifier: "RequestStoryboardID") as! RequestorViewController
let rootViewController = self.window!.rootViewController as! UITabBarController
rootViewController.present(requestor, animated: false, completion: nil)

Like what you mention, if the selectedViewController of the UITabBarController is a UINavigationController, you could do a pushViewController instead.
First, you will have to get the currently on screen UINavigationController. Then perform a pushViewController with requestor as a parameter.
presentedNavigationController = rootViewController.selectedViewController as! UINavigationController
presentedNavigationController.pushViewController(requestor, animated: true)

Related

Show navigation to Controller programatically

I am changing a menu VC over from StoryBoard to programatic operation.
When I want to load another VC I was using the Action Segue "Show".
The temporary code I am using works but pops the VC over the top. Can you action the "Show" equivalent programatically, and if so how?
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "SunriseSunsetResultsViewController")
self.present(newViewController, animated: true, completion: nil)
To do what a Show segue used to do, replace present with show:
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "SunriseSunsetResultsViewController")
self.show(newViewController, sender: self)
Note, however, that this will do the same thing as present unless self.navigationController is not nil. In other words, you cannot do the sideways navigation you were doing before unless a navigation controller is in charge of the interface.
Instead of show you could say pushViewController etc., but the same caveat applies. Only a navigation controller can do what you were doing previously.

Skip login screen from scene delegate in tabbed bar navigation App

I am trying to skip the login screen and go straight to the MainViewController when the user is logged in. However the problem is that I have a Tab Bar Controller and Navigation Controller between the login and the main vc. After extensive search I wrote the below code
func showMainViewController() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainViewController: MainViewController = storyboard.instantiateViewController(withIdentifier: "MainViewController") as! MainViewController
let navigationController = UINavigationController(rootViewController: mainViewController)
//It removes all view controllers from the navigation controller then sets the new root view controller and it pops.
window?.rootViewController = navigationController
// //Navigation bar is hidden
// navigationController.isNavigationBarHidden = true
}
However it fails to show the tab bar view controller. Any help is appreciated.
try this
func showMainViewController() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainViewController: MainViewController = storyboard.instantiateViewController(withIdentifier: "TabBar")
window?.rootViewController = mainViewController
window?.makeKeyAndVisible()
}
you should instantiate TabBar no main viewController. since is instantiate inmediatrly is if first index or set the selected index

Opening a View Controller that is connected to a navigation Controller programatically

I am using AKSwiftSlideMenu as basis for an app.
I have a view controller (HomeVC) that is connected to a navigation controller.
If the storyboard entry point is pointing to HomeVC then I get the menu of course, but my app needs to start without the menu and only after certain screens and tasks that are done i want to navigate to HomeVC and allow user access to the menu.
I noticed that if a i place a button on a starting view controller that does not have a connection to the navigation controller, and connect that button directly to the Navigation controller by drag+cntrl then pressing the button will get me from a view controller without a menu to HomeVC and show the menu.
How do i do that programmatically
Thanks in advance for any help
edit: I have tried the following code
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "Home") as! UINavigationController
self.present(newViewController, animated: true, completion: nil)
which did not work resulting with the following err
Could not cast value of type 'myApp.HomeVC' (0x10a159280) to 'UINavigationController' (0x10cc2d3c8).
let newViewController = storyBoard.instantiateViewController(withIdentifier: "Home") as! UINavigationController
s
"Home" is not a UINavigationController. Remove as! UINavigationController from this line and the error will go away.
thank you Daniel for telling me to instantiate navigation controller. Ended up giving navigation controller a storyboard id named ccontroller and the following code does what I needed
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "ccontroller") as! UINavigationController
self.present(vc, animated: true, completion: nil)

Present Tab of TabBarController Through parent ViewController

I want to present a certain index of my tabBarController but first go through another custom ViewController.
In the image above. i want to present the yellow viewcontroller, which will automatically present my TabBar Controller, but i want the tab bar controller to show a specific index.
i present the yellow ViewController with the code below:
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let tbc = storyBoard.instantiateViewController(withIdentifier: "SWRevealViewController") as! SWRevealViewController
tbc.modalTransitionStyle = .crossDissolve
self.present(tbc, animated: true, completion: nil)
normally when presenting a tab on a tabBarController i would use the following code:
let tbc = self.storyboard!.instantiateViewController(withIdentifier: "MyTabController") as! UITabBarController
tbc.selectedIndex = 1
tbc.modalPresentationStyle = .overCurrentContext
tbc.modalTransitionStyle = .coverVertical
self.present(tbc, animated: true, completion: nil)
how would i go about loading the specific index of the tab bar through the yellow viewcontroller? it is a custom class with a custom segue:
In situations like this I would usually pass on the index you want from your yellow controller to the tabBarController (using let's say, an instance variable). Which then can be set by the tab bar controller to the index you want.

Swift ios reset viewcontroller hierarchy

In storyboard my app is designed as:
Navigation VC -> VC1
What I am trying to do is to segue to another VC but reset the menu-hierarchy so that i dont have the old VC's stacked in the backgound
What I want to do is:
Navigation VC -> VC1 -> VC2 -> NEW VC with Navigation reseted
So when a user logs in and enters the account VC/Page the navigation stack should be resetted when hitting the account VC/Page
Is this possible to do?
If you do not want to add the view controllers to your navigation controller, every View controller you navigate to you can set that as the root view controller of your navigation controller and it won't be added in your stack.
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let yourViewController: ViewController = storyboard.instantiateViewControllerWithIdentifier("respectiveIdentifier") as! ViewController
let navigationController = self.view.window?.rootViewController as! UINavigationController
navigationController.setViewControllers([yourViewController], animated: true)
My solution same as above but one line less
let yourViewControllerObejct = self.storyboard?.instantiateViewControllerWithIdentifier("YourViewControllerId") as? YourViewController
let navigationController = self.view.window?.rootViewController as! UINavigationController
navigationController.setViewControllers([yourViewControllerObejct!], animated: true)

Resources