I have Side Menu this as SlideMenu. But I want it to start from my ShopHome screen. And in my app my root/initial VC is Login page. When I use the below code it goes directly to ShopHome. But instead I want my app to start from Login and then menu on ShopHome screen. I tried changing root to my LoginVC but then menu doesn't work when I'm on ShopHome page.
AppDelegate
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainViewController = storyboard.instantiateViewController(withIdentifier: "ShopHomeVC") as! ShopHomeVC
let rightViewController = storyboard.instantiateViewController(withIdentifier: "RightMenuVC") as! RightMenuVC
let nvc: UINavigationController = UINavigationController(rootViewController: mainViewController)
let slideMenuController = SlideMenuController(mainViewController: nvc, rightMenuViewController: rightViewController)
self.window?.rootViewController = slideMenuController
self.window?.makeKeyAndVisible()
I checked Slide Menu
Use this and delegate add
let leftViewController = storyboard.instantiateViewController(withIdentifier: "LeftViewController") as! LeftViewController
let rightViewController = storyboard.instantiateViewController(withIdentifier: "RightViewController") as! RightViewController
let nvc: UINavigationController = UINavigationController(rootViewController: mainViewController)
let slideMenuController = SlideMenuController(mainViewController: nvc,leftMenuViewController: leftViewController, rightMenuViewController: rightViewController)
slideMenuController.automaticallyAdjustsScrollViewInsets = true
slideMenuController.delegate = mainViewController
self.window?.rootViewController = slideMenuController
self.window?.makeKeyAndVisible()
This is how I solved it. On my LoginButton action changed my root.
#IBAction func loginButtonAction(_ sender: Any) {
let mainViewController = storyboard.instantiateViewController(withIdentifier: "ShopHomeVC") as! ShopHomeVC
let rightViewController = storyboard.instantiateViewController(withIdentifier: "RightMenuVC") as! RightMenuVC
let nvc: UINavigationController = UINavigationController(rootViewController: mainViewController)
let slideMenuController = SlideMenuController(mainViewController: nvc, rightMenuViewController: rightViewController)
UIApplication.shared.delegate?.window?.rootViewController = slideMenuController
}
Thanks to #kaminara4 (GitHub)
Related
I have used SceneDelegate to change the rootviewcontroller after login action. It works fine but when I logout I am not able to perform navigation again.
Here is my code for Scenekit:
let status = UserDefaults.standard.bool(forKey: UserDefaultKeys.status)
var rootVC : UIViewController?
if(status == true){
rootVC = UIStoryboard(name: AppStoryBoardName.main, bundle: nil).instantiateViewController(withIdentifier: TabBarViewController.className) as? TabBarViewController
}else{
rootVC = UIStoryboard(name: AppStoryBoardName.main, bundle: nil).instantiateViewController(withIdentifier: LoginViewController.className) as? LoginViewController
}
guard let root = rootVC else {return }
let nav = UINavigationController(rootViewController: root)
window?.rootViewController = nav
My logout code:
appUserDefaults.set(false, forKey: UserDefaultKeys.status)
appUserDefaults.synchronize()
let loginVC = self.storyboard?.instantiateViewController(withIdentifier: LoginViewController.className) as? LoginViewController
let window = UIApplication.shared.windows.first
window?.rootViewController = loginVC
And my login Button Action: (It doesnt works after logout action)
guard let controller = self.storyboard?.instantiateViewController(withIdentifier: VerificationViewController.className) as? VerificationViewController else { return }
controller.mobile = phoneTextField.text ?? ""
self.navigationController?.pushViewController(controller, animated: true)
It is not working because there is an inconsistency in hierarchy of view-controllers on logout button action and in sceneKit.
In sceneKit code you are embedding your LoginViewController in navigation controller and then assign the navigation controller as the windows root view-controller.
let status = UserDefaults.standard.bool(forKey: UserDefaultKeys.status)
var rootVC : UIViewController?
if(status == true){
rootVC = UIStoryboard(name: AppStoryBoardName.main, bundle: nil).instantiateViewController(withIdentifier: TabBarViewController.className) as? TabBarViewController
} else{
rootVC = UIStoryboard(name: AppStoryBoardName.main, bundle: nil).instantiateViewController(withIdentifier: LoginViewController.className) as? LoginViewController
}
guard let root = rootVC else {return }
// Embedding the specific controller in navigation controller and assigning navigation controller as windows root.
let nav = UINavigationController(rootViewController: root)
window?.rootViewController = nav
In that case you will have navigation controller in LoginViewController and the login button action works perfect i.e.
self.navigationController?.pushViewController(controller, animated: true)
But on logout you simply assign your LoginViewController as the windows root i.e.
appUserDefaults.set(false, forKey: UserDefaultKeys.status) appUserDefaults.synchronize()
let loginVC = self.storyboard?.instantiateViewController(withIdentifier: LoginViewController.className) as? LoginViewController
let window = UIApplication.shared.windows.first
// loginVC is not embedded in Navigation Controller
window?.rootViewController = loginVC
After the above transition the LoginViewController will not navigation controller so the optional chaining of pushingViewController in login button action will fails i.e.
self.navigationController?.pushViewController(controller, animated: true)
Keep it consistent by embedding the LoginViewController in Navigation Controller even on logout, update your logout action code to :
appUserDefaults.set(false, forKey: UserDefaultKeys.status) appUserDefaults.synchronize()
let loginVC = self.storyboard?.instantiateViewController(withIdentifier: LoginViewController.className) as? LoginViewController
let window = UIApplication.shared.windows.first
// Embed loginVC in Navigation Controller and assign the Navigation Controller as windows root
let nav = UINavigationController(rootViewController: loginVC)
window?.rootViewController = nav
I can't push from initial viewController after using this code
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: Identifier)
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
You have to Embed UIViewController in a UINavigationController. Try this one:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: Identifier)
let navController = UINavigationController(rootViewController: initialViewController)
self.window?.rootViewController = navController
self.window?.makeKeyAndVisible()
Why I am getting an exception while navigating. I am a beginner for the iOS development. I am navigating once the user has log in. I have used following code. I don't understand what I am missing.
I got the following exeption at last line -
Fatal error: Unexpectedly found nil while unwrapping an Optional value
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyBoard.instantiateViewController(withIdentifier: "taskListController") as! TaskListController
self.navigationController!.pushViewController(secondViewController, animated: true)
Please let me know my mistake.
You must add a navigation controller first before you push a VC
Navigation controller using code
func goToMyVC(){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let mainView = storyboard.instantiateViewController(withIdentifier: "yourVC") as? yourVC
{
self.window = UIWindow(frame: UIScreen.main.bounds)
let nav1 = UINavigationController()
nav1.isNavigationBarHidden = true //Show or hide nav bar
nav1.viewControllers = [mainView]
self.window!.switchRootViewController(nav1)
self.window?.makeKeyAndVisible()
} }
In your viewcontroller call this function,
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.goToMyVC()
Navigation controller from story
let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "controller") as? controller
self.navigationController?.pushViewController(vc!, animated: true)
Try the blow codes,
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "taskListController") as? TaskListController
self.navigationController?.pushViewController(secondViewController!, animated: true)
and make sure that you embedded the login view controller in a navigation controller
I am trying to push SWRevealViewController from appdelegate at first, the status bar is shown only temporary and after loading the viewController its not appearing.
Here is my code and I am using swift:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let sw = storyboard.instantiateViewController(withIdentifier: "revealControllerStoryboard") as! SWRevealViewController
self.window?.rootViewController = sw
let destinationController = storyboard.instantiateViewController(withIdentifier: "searchViewStoryboard") as! SearchViewController
let navigationController = UINavigationController(rootViewController: destinationController)
sw.pushFrontViewController(navigationController, animated: true)
How to show the status bar permanently?
and heres the pict
Try this EDIT
let frontNavigationController:UINavigationController
let rearNavigationController:UINavigationController
let revealController = SWRevealViewController()
var mainRevealController = SWRevealViewController()
let menuTable = self.storyboard?.instantiateViewController(withIdentifier: "MenuViewController")as! MenuViewController
let homepage = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
frontNavigationController = UINavigationController(rootViewController: homepage)
rearNavigationController = UINavigationController(rootViewController: menuTable)
rearNavigationController.setNavigationBarHidden(true, animated: false)
revealController.frontViewController = frontNavigationController
revealController.rearViewController = rearNavigationController
revealController.delegate = self
mainRevealController = revealController
UIApplication.shared.delegate!.window?.rootViewController = mainRevealController
self.window = UIWindow(frame: UIScreen.main.bounds)
somehow adding this line make the status bar show again
In the scenario where you have a viewController which you want to present as root view above everything else what is the right way to do this?
let Storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let MY_VIEW = Storyboard.instantiateViewControllerWithIdentifier("VIEWID")
//Is this the right way?
UIApplication.sharedApplication().delegate.window?.rootViewController?.presentViewController(MY_VIEW, animated: true, completion: nil)
//Or this?
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(MY_VIEW, animated: true, completion: nil)
In other words why would you use UIApplication.sharedApplication().delegate.window? over UIApplication.sharedApplication().keyWindow?.rootViewController? and in what scenarios? What would be the pros/cons of using one or the other?
You can do as follow.
let rootController = storyboard.instantiateViewControllerWithIdentifier("VIEWID") as! SplashVC
if self.window != nil {
self.window!.rootViewController = rootController
}
advantage of this is not getting crash when window is nil.
Another way is that(Most secure way i think)
let navigationController:UINavigationController = storyboard.instantiateInitialViewController() as! UINavigationController
let rootViewController:UIViewController = storyboard.instantiateViewControllerWithIdentifier("VIEWID") as! LoginVC
navigationController.viewControllers = [rootViewController]
self.window?.rootViewController = navigationController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController: MainViewController = storyboard.instantiateViewControllerWithIdentifier("MainViewController") as! MainViewController
let rootViewController = self.window!.rootViewController as! UINavigationController
rootViewController.pushViewController(viewController, animated: true)