How to go from appDelegate to viewController [duplicate] - ios

This question already has answers here:
Storyboard - refer to ViewController in AppDelegate
(5 answers)
Closed 4 years ago.
if i have two viewControllers and i want when condition succeeded i want to go to another ViewController.
but i want to check every time the app launched so i stored the value on userDefaults and in appDelegate i checked for this value.
when i print the value i get it but i can not go to the desired controller.
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let active:Bool = defaults.bool(forKey: "activeBooking")
if active {
print("active \(active)")
let rootViewController = self.window!.rootViewController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Final", bundle: nil)
let setViewController = mainStoryboard.instantiateViewController(withIdentifier: "finalBooking") as! BookingFromCurrentLocationVC
rootViewController?.navigationController?.popToViewController(setViewController, animated: false)
}
return true
}
i print the value in other controller and it return me true(my value) so why i can not go to another controller

You can try this:
In appDelegate and in didFinishLaunching
You can store this value in UserDefault and then check the condition:
if condition == true{
goToVC1()
}else{
goToVC2
}
func goToVC1() {
let storyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let ObjVC1: ViewController = storyboard.instantiateViewController(withIdentifier: "VC1") as! VC1
let navigationController : UINavigationController = UINavigationController(rootViewController: ObjVC1)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
}
func goToVC2() {
let storyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let ObjVC2: ViewController = storyboard.instantiateViewController(withIdentifier: "VC2") as! VC2
let navigationController : UINavigationController = UINavigationController(rootViewController: ObjVC2)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
}

Add a segue from Navigation controller to desired View Controller (with segue identifier "finalBookingVC") and replace the code inside your if condition with:
self.window?.rootViewController!.performSegue(withIdentifier: "finalBookingVC", sender: nil)

You can initiate your view controller in AppDelegate as below.
Perform your condition check and set the StoryboardID and ViewControllerID as per your requirement.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
//check your condition here and change the Storyboard name and ViewController ID as required
let vc = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "HomeVCID") as! HomeController
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
return true
}

The first thing you need to check if an application is active and already open (top controller is finalBookingVC) then no need to do anything,
second thing finalBookingVC if already available in a stack then no need to push at that time you need to pop view controller.
If finalBookingVC is not available on the stack then you need to push this controller.
func gotoController() {
let navigationController : UINavigationController! = self.window!.rootViewController as! UINavigationController;
let arrViewController = navigationController;
if arrViewController != nil && !(arrViewController?.topViewController is finalBookingVC) {
var finalBookingVCFound:Bool = false;
for aViewController in (arrViewController?.viewControllers)! {
if aViewController is finalBookingVC {
finalBookingVCFound = true;
_ = navigationController?.popToViewController(aViewController, animated: true);
break;
}
}
if !finalBookingVCFound {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil);
let objVC:finalBookingVC = mainStoryboard.instantiateViewController(withIdentifier: "finalBookingVC") as! finalBookingVC;
navigationController?.pushViewController(objVC, animated: true);
}
}
}

Related

sideMenu not displayed after login

I have included kukushi side menu. I have done things according to the documentation. The screen shot with the codes in app delegate are below:
func setUpHomeVC() {
var window: UIWindow?
let storyBoard = UIStoryboard.init(name: "Dashboard", bundle: Bundle.main)
let contentViewController = storyBoard.instantiateViewController(withIdentifier: "DashboardViewController") as! DashboardViewController
let menuViewController = storyBoard.instantiateViewController(withIdentifier: "MenuViewCOntroller") as! MenuViewCOntroller
SideMenuController.preferences.basic.menuWidth = 240
SideMenuController.preferences.basic.statusBarBehavior = .hideOnMenu
SideMenuController.preferences.basic.position = .sideBySide
SideMenuController.preferences.basic.direction = .left
SideMenuController.preferences.basic.enablePanGesture = true
SideMenuController.preferences.basic.supportedOrientations = .portrait
SideMenuController.preferences.basic.shouldRespectLanguageDirection = true
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = SideMenuController(contentViewController: contentViewController,
menuViewController: menuViewController)
window?.makeKeyAndVisible()
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
setUpHomeVC()
return true
}
The identifier, class and module has been added according to the documentation. After login there is dashboard which consist of menu button. On login the code is:
private func goToDashboard() {
let dashboard = UIStoryboard(name: "Dashboard", bundle: nil)
let navView = dashboard.instantiateViewController(identifier: "DashboardViewController") as DashboardViewController
present(navView,animated: false)
}
On dashboard there is a button which have click event:
#IBAction func btnMenuClicked(_ sender: Any) {
print("Menu button has been clicked")
self.sideMenuController?.revealMenu(animated: true)
}
when I click on that button the print function is called but the menu is not revealed.
Can anyone explain it. Thanks in advance.
You can setup your appDelegate like this,
func setUpHomeVC() {
let storyboard = UIStoryboard(name: "Your Login Storyboard", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "LoginVC")
self.window?.rootViewController = initialViewController
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
setUpHomeVC()
return true
}
And in your login event:
private func goToDashboard() {
self.pushVC()
}
private func pushVC() {
let storyBoard = UIStoryboard.init(name: "Dashboard", bundle: Bundle.main)
let contentViewController = storyBoard.instantiateViewController(withIdentifier: "DashboardViewController") as! DashboardViewController
let menuViewController = storyBoard.instantiateViewController(withIdentifier: "MenuViewCOntroller") as! MenuViewCOntroller
SideMenuController.preferences.basic.menuWidth = 240
SideMenuController.preferences.basic.statusBarBehavior = .hideOnMenu
SideMenuController.preferences.basic.position = .sideBySide
SideMenuController.preferences.basic.direction = .left
SideMenuController.preferences.basic.enablePanGesture = true
SideMenuController.preferences.basic.supportedOrientations = .portrait
SideMenuController.preferences.basic.shouldRespectLanguageDirection = true
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = SideMenuController(contentViewController: contentViewController,
menuViewController: menuViewController)
window?.makeKeyAndVisible()
}
Your DashboardVC should be in a navigation controller for sidemenu to present. Try pushing the controller instead of presenting it.If you have the controller in a different storyboard, you can use this function:
func pushVC(storyboardName : String, vcname : String) {
let vc = UIStoryboard.init(name: storyboardName, bundle: Bundle.main).instantiateViewController(withIdentifier: vcname)
self.navigationController?.pushViewController(vc, animated: true)
}
Also, I would suggest you learn about when to push, present, and make root view controllers as all serve different purposes.
I think your current implementation is wrong. The problem is we need to implement and push the view controllers as SideMenuControllers bundle, not separate ViewControlers
If you want to have the side menu after login, then set your login page first in your didFinishLaunchingWithOptions.
Then you can call setUpHomeVC from your loginVC.

Load A View Controller programmatically from a UIView

I am using the following from within a class to call a UIViewController. The UIViewController loads, but then becomes unresponsive after loading.
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let homeC = storyboard.instantiateViewController(withIdentifier:
"ViewJoeProfileController") as? ViewJoeProfileController
if homeC != nil {
homeC!.view.frame = (self.window!.frame)
self.window!.addSubview(homeC!.view)
self.window!.bringSubview(toFront: homeC!.view)
}
}
Any suggestions to make the UIViewController being loaded responsive would really help!
If you specifically want to add to the window, you should do it the proper way and add the whole ViewController:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
guard let window = UIWindow(frame: UIScreen.mainScreen().bounds) else { return true }
if let homeC = storyboard.instantiateViewController(withIdentifier: "ViewJoeProfileController") as? ViewJoeProfileController {
window.rootViewController = mainViewController
window.makeKeyAndVisible()
}
return true
}
But honestly that structure still doesn't seem correct. Why are you adding a view to the window, instead of using an initial view controller and then adding to itsviews, or segueing to different ViewControllers?.
Try using this I need to make root View Controller
let storyBoard = UIStoryboard.init(name: "Main", bundle: nil)
let vc = storyBoard.instantiateViewController(withIdentifier: "ViewJoeProfileController") as! ViewJoeProfileController
let nav = UINavigationController(rootViewController: vc)
nav.isNavigationBarHidden = true
self.window?.rootViewController=nav
self.window?.makeKeyAndVisible()

Display a particular viewcontroller in Xcode/swift using if else conditional statements

I want a to have a conditional if statement to be run immediately when the app is open. Basically, it will be
if x = true {
//segue to viewcontroller1
} else {
//stay on this page
}
This will be in Xcode and coded in swift (obviously the syntax is wrong)... what is the appropriate way to write the syntax to segue to a particular view controller if the condition is true and stay on the one that normally is opened up to upon opening the app? Also, where do I put this? I considered the viewdidload method in the, normally, first displayed viewcontroller, but the variable needs to be checked before the view loads, such that the view changes to a different one if the condition is true and that one opens first instead?
Edit: I tried to set the code in the AppDelegate.swift as follows:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if x{
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let ViewController = mainStoryBoard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = ViewController
} else{
//same code as above but to different VC
}
return true
}
But when I run this I get an error in the appDelegate saying that "libc++abi.dylib: terminating with uncaught exception of type NSException". What is the right way to modify this code?
If you want to select the scene before presenting. You can add the following in appDelegate.swift, in application(application: UIApplication, didFinishLaunchingWithOptions):
var id = x ? "id1" : "id2"
self.window = UIWindow(frame: UIScreen.main.bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let exampleVC: UIViewController = mainStoryboard.instantiateViewController(withIdentifier: id) as UIViewController
self.window?.rootViewController = exampleVC
self.window?.makeKeyAndVisible()
Make sure you name the scenes in storyboard
If you OK with the first scene showing and then choosing to segue:
if x {
self.performSegue(withIdentifier: "id1", sender: self)
} else {
self.performSegue(withIdentifier: "id2", sender: self)
}
Again, make sure to name the segues in storyboard
Another option, use UINavigationController. Set a Navigation Controller as your root view controller
let id = x ? "id1" : "id2"
let mainStoryboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
let exampleVC = mainStoryboard.instantiateViewController(withIdentifier: id) as UIViewController
let navigationController = UINavigationController(rootViewController: exampleVC)
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window!.rootViewController = navigationController
self.window!.makeKeyAndVisible()

How to change the initial view controller through swift code

I'm developing an app with initial view controller as "Navigation controller". The app contains 2 ideas to implement.
1) From the RegisterViewController, User has to register the mobile no with verification //from sms or call, After verified it enters into HomeViewController( Condition: when the user install the app for the 1st time it shows the RegisterViewController)
2) If the app is already get installed into the iPhone and the user also register the mobile no, then the user opens the same app now the initialViewController must be the HomeViewController
How can I achieve this idea through swift code?
Implement this logic in your appdelegate class:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let isRegistered = NSUserDefaults.standardUserDefaults().boolForKey("ALLREADY_REGISTER")
if isRegistered == true{
// implement home view controller
let homeViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("HomeVC") as! HomeViewController
self.window?.rootViewController = homeViewController
self.window?.makeKeyAndVisible()
}else{
// implement register view controller
let registerViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("RegisterVC") as! RegisterViewController
self.window?.rootViewController = registerViewController
self.window?.makeKeyAndVisible()
}
return true
}
Then when first time register completed successfully then set bool variable true for the key ALLREADY_REGISTER
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "ALLREADY_REGISTER")`
do like
var viewController: UIViewController!
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
var storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
if NSUserDefaults.standardUserDefaults().objectForKey("notRegistered") == nil
{
viewController = storyboard.instantiateViewControllerWithIdentifier("RegisterViewController")
}
else {
if NSUserDefaults.standardUserDefaults().objectForKey("notRegistered") as! String == "registred"
{
viewController = storyboard.instantiateViewControllerWithIdentifier("HomeViewController")
}
else
{
viewController = storyboard.instantiateViewControllerWithIdentifier("RegisterViewController")
}
// if you want to create the UINavigationController use this
let nav = UINavigationController(rootViewController: viewController)
self.window!.rootViewController = nav
else directly access use this
self.window!.rootViewController = viewController
self.window.makeKeyAndVisible()
// Override point for customization after application launch.
return true
}
on registration page after the success save like
//Save
NSUserDefaults.standardUserDefaults().setObject("registred", forKey: "notRegistered")
you have to change rootViewController instead of initialViewController. when user verified and enters into HomeViewController store flag in NSUserDefaults.then every time in AppDelegate didFinishLaunchingWithOptions check user is already entered in HomeViewController using NSUserDefaults.
let appdelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var homeViewController = mainStoryboard.instantiateViewControllerWithIdentifier("HomeViewController") as! HomeViewController
let nav = UINavigationController(rootViewController: homeViewController)
appdelegate.window!.rootViewController = nav

Unable to instantiate rootViewController from within AppDelegate

My onboarding process (login/signup) lives outside of the UINavigationController chain, but when the login is authenticated I call a method in the appdelegate thats supposed to instantiate the rootViewController and then push to it. I've tried two things:
The snippet above worked in appDelegate from a method that gets called when a local notification is responded to, but not in this case.
self.window?.makeKeyAndVisible()
self.window?.rootViewController?.navigationController?.popToRootViewControllerAnimated(true)
And heres another method I tried:
let rootViewController = self.window?.rootViewController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let dashboard = mainStoryboard.instantiateViewControllerWithIdentifier("DashboardViewController") as! DashboardViewController
rootViewController!.navigationController?.popToViewController(dashboard, animated: true)
Neither of these work. What am I doing wrong?
My login view controller also live outside of my tab bar controller so this is what I did:
In the appDelegate:
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let loginVC = storyboard.instantiateViewControllerWithIdentifier("LoginVC") as! LoginViewController
self.window?.rootViewController = loginVC
self.window!.makeKeyAndVisible()
return true
}
then I have a method in my loginViewContoller.swift:
#IBAction func loginPushed(sender: AnyObject) {
//other stuff here
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let tabBarController = UITabBarController()
let first = mainStoryBoard.instantiateViewControllerWithIdentifier("firstNavController") as! UINavigationController
let second = mainStoryBoard.instantiateViewControllerWithIdentifier("secondNavController") as! UINavigationController
let third = mainStoryBoard.instantiateViewControllerWithIdentifier("thirdNavController") as! UINavigationController
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let controllers = [first, second, third]
tabBarController.viewControllers = controllers
appDelegate.window!.rootViewController = tabBarController
appDelegate.window!.makeKeyAndVisible()
}
I think you shouldn't call the 'popToRootViewController', you can reassignment the window.rootViewController~

Resources