How to instantiate a viewcontroller with an embedded navigation controller programmatically swift? - ios

I'm trying to instantiate a viewcontroller that has a navigation controller embedded in it from the AppDelegate. Here's what my code looks like:
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let dm = DefaultsManager.sharedManager
if dm.rememberMe == true {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("VolunteerVC")
self.window!.rootViewController = vc
self.window?.makeKeyAndVisible()
}
the right viewcontroller is instantiated but the navigation controller that was embedded in it is now missing. Any idea how to instantiate it with the nav controller still connected?

Figured it out, give the nav controller a name under storyboard ID in the storyboard and for the line:
let vc = storyboard.instantiateViewControllerWithIdentifier("VolunteerVC")
replace the name of the viewcontroller with the name you gave the navigation controller.

Related

Show viewcontroller by storyboard id inside UITabBarController

I am trying to show a specific viewcontroller, inside my UITabBarController by using the viewcontrollers storyboard id.
I can only get the viewcontroller to be shown without the UITabBarController.
How do I also show the UITabBarController?
I have tried this:
let identifier = "stats_view"
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: identifier)
window?.rootViewController = vc
Which gave me the problem listed above.
try the following code.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if let myTabBar = self.window.rootViewController as? UITabBarController { // Getting Tab Bar
myTabBar.selectedIndex = 2 //Selecting tab here
return true
}
}
You should set selectedIndex of tabBarController to view specific viewController which are embedded in tabBarController. Use following code.
self.tabBarController?.selectedIndex = 1

Limit Navigation Controller to a set of UIViewControllers

Is it possible to limit the NavigationController to a certain set of UIViewControllers. See the image, I want the navigation controller, but only for the login/create user session. Once logged in, I obviously don't want the user to be able to go back (except log out). How can I accomplish that? I can't figure it out.
Go to Storyboard -> select NavigationController -> Attributes Inspector -> uncheck "Shows Navigation Bar" property
Then select relationship between Login/SignUp And TabBarController, and delete it.
Once login you can set your TabBarController(or any related controller) as the rootViewController. And when app launches you can check it in your AppDelegate.swift file like this,
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if Auth.auth().currentUser != nil {
let tabBarController = storyboard.instantiateViewController(withIdentifier: "tabBarcontroller") as! TabBarController
self.window?.rootViewController = tabBarController
self.window?.makeKeyAndVisible()
}
else
{
let loginNavController = storyboard.instantiateViewController(withIdentifier: "LoginNavController") as! UINavigationController
self.window?.rootViewController = loginNavController
self.window?.makeKeyAndVisible()
}
return true
}
You could change the stack of your navigation controller when needed, e.g:
func logIn() {
//Delete all presented view controllers up to a point
navigationController.setViewControllers([], animated: false)
//Create new view controller
let viewController = ....
navigationController.pushViewController(viewController, animated: true)
}
Take a look at setViewControllers, that may give you some idea.
If you want to leave previous view controllers in stack, and just forbid user to pop to them, then it may be the best solution to subclass UINavigationController and override func popViewController(animated: Bool) -> UIViewController?

self.navigationController is always nil

UI flow:
AppDelegate
-->
LoginViewController (not in the storyboard)
-->
navigation controller (in the storyboard)
-->
PFQueryTableViewController (in the storyboard) named "OrdersVC"
This is the navigation controller with OrdersVC:
This is my AppDelegate:
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// ...
// initial VC
let VC = LoginViewController()
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window!.rootViewController = VC
window!.makeKeyAndVisible()
return true
}
The above works fine. Then, from LoginViewController, I am then trying to display my storyboard's initial VC which is a navigation controller hosting a PFQueryTableViewController. Note that LoginViewController is not in the storyboard.
let destVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("OrdersVC") as! UITableViewController
// will throw "unexpectedly found nil"
let navController = UINavigationController(rootViewController: destVC)
navController.pushViewController(destVC, animated: true)
// will throw "unexpectedly found nil"
self.presentViewController(navController, animated: true, completion: nil)
Problem is that in my PFQueryTableViewController's viewDidLoad and viewDidAppear the following statement is always nil:
// navitaionController is nil
self.navigationController!.navigationBar.translucent = false
So how can I correctly instantiate PFQueryTableViewController inside its navigation controller?
You are instantiating the OrdersVC instead of instantiating the navigation controller into which it is embedded and which is the "initial" view controller of your storyboard. Use instantiateInitialViewController instead of using the identifier.
let nav = storyboard.instantiateInitialViewController()
self.window!.rootViewController = nav
The reason for the confusion is that you are "unlinking" the initial view controller from the storyboard with your login controller. You have to add the initial view controller back to the main window.

When set root view controller programmatically navigation and tab bar missing

App delegate code:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myViewController = storyboard.instantiateViewControllerWithIdentifier("MyViewController") as UIViewController
if self.window != nil {
self.window!.rootViewController = myViewController
}
When I load app without this code everything is fine.
But if I run with this code view is loaded but navigation and tab bar are missing.
What am I missing here?
I am using storyboard.
This is code that work:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainRootController = storyboard.instantiateViewControllerWithIdentifier("MainViewController") as UIViewController
if self.window != nil {
let navigationController:UINavigationController = storyboard.instantiateInitialViewController() as UINavigationController
navigationController.viewControllers = [mainRootController]
self.window!.rootViewController = navigationController
}
return true
Before adding root view controller you must be allocate memory for navigation controller and then navigation controller take as a root view controller .
UINavigationController *navigationController=[[UINavigationController alloc] initWithRootViewController:yourViewController];
[[UINavigationBar appearance]setTintColor:[UIColor whiteColor]];
self.window.rootViewController = navigationController;

RootView navigation in swift

I am an Objectie-C developer. for the root view navigation i used the below code in Objectie-c
FirstViewController *fvc=[[FirstViewController alloc]init];
UINavigationController *nv=[[UINavigationController alloc]initWithRootViewController:fvc];
self.window.rootViewController=nv;
for my new project I am making it in swift.I just want to make RootView navigation from AppDelegate.swift.
Check below code. first we create window. then alloc init viewcontroller. and then alloc navigation controller with rootcontroller as viewcontroller. and Window's root controller as navigation controller.
var window: UIWindow?
var navC : UINavigationController?
var vc:ViewController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
// alloc init window
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
// view controller
self.vc = ViewController(nibName: "ViewController", bundle: nil);
// create navigation controller with root = vc.
self.navC = UINavigationController(rootViewController: self.vc!);
self.navC?.navigationBar.hidden = true;
// window's root controller as navigation controller.
self.window?.rootViewController = self.navC
self.window?.makeKeyAndVisible()
return true
}
Maybe this will help you.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
var rootVie: FirstViewController = FirstViewController() // this is allocation method in swift
if let window = self.window{
window.rootViewController = rootVie
}
return true
}
need referene use this link

Resources