How to set root view controller? - ios

I want to make slide out menu. For this I have to create UINavigationViewController which will controlMenuViewController(Table View) and ProfileViewController(Content View)
I want to set UINavigationViewController like a rootViewController, for this I wrote this code in AppDelegate.swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let nav1 = UINavigationController()
let mainView = MainViewController(menuViewController: nil, contentViewController: nil) //ViewController = Name of your controller
nav1.viewControllers = [mainView]
self.window?.rootViewController = nav1
self.window?.makeKeyAndVisible()
return true
}
MainViewController is my UINavigationViewController.
But here I have error
nil is not compatible with expected argument type 'UIViewController'
What I should do?

You pass nil here: MainViewController(menuViewController: nil, contentViewController: nil) instead of some view controllers. That's probably the reason it doesn't compile.
You embed your MainViewController instance, which is already UINavigationController, into another one UINavigationController. That looks wrong too.

Here is an example:
LoginViewController *loginController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"loginController"]; //or the homeController
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController = navController;`

This error means you can't set menuViewController and contentViewController to nil, they are not optional

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

Can't push view controller in AppDelegate with TabBarController

I have a TabBarController as a rootViewController for my app. And I'm trying to push view controller when user clicks to notification. But code isn't working. How can I push view controller from AppDelegate without storyboards.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = TabBarController()
window?.makeKeyAndVisible()
return true
}
You can try to embed the tab inside a navigation
let nav = UINavigationController(rootViewController: TabBarController())
nav.isNavigationBarHidden = true
window?.rootViewController = nav
Then inside didReceiveRemoteNotification
if let nav = self.window?.rootViewController as? UINavigationController {
nav.pushViewController(////
}
to show nav inside the vc viewDidLoad
self.navigationController?.isNavigationBarHidden = false
You should not embed UITabBarController in a UINavigationController (as written in Apple Documentation init and push). However, it's working.
The correct solution is to use UINavigationController as tabs in UITabBarController:
let tabBarController = TabBarController()
tabBarController.viewControllers = [UINavigationController(rootViewController: vc1), UINavigationController(rootViewController: vc2)]
window?.rootViewController = tabBarController
and then push to them:
let navigationController = tabBarController.selectedViewController as? UINavigationController
navigationController?.pushViewController(notificationViewController)
Or you can create a new view controller and settng it as a rootViewController of window:
window?.rootViewController = notificationViewController
But this requires more navigation code to setting back tabBarController after dismissing notification etc.

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

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.

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;

Resources