Why DetailViewController pop to first DetailViewController with Tabbar and Navigation Controller? - ios

First of all I am using storyboard. My ViewController hierarchy like this NavigationController -> SplashScreen -> LoginScreen -> MainTabBarController -> MainNavigationController -> MainViewController -> DetailViewController.
When I click a button on the DetailViewController page does not back to MainViewController. It is going to LoginScreen.
I tried this codes within addToBasket action in DetailViewController.
#IBAction func addBasket(_ sender: Any) {
SingletonCart.sharedFood.food.append(food!)
let mainView = self.storyboard?.instantiateViewController(withIdentifier: "FoodOrder") as! MainViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
self.navigationController?.popViewController(animated: true)
dismiss(animated: true)
}
Here is my loginButton codes for make MyTabBarController as rootViewController.
#IBAction func loginButton(_ sender: Any) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "MainTabBarController")
self.window?.rootViewController = viewController
}

In your approach the RootViewController is Navigation controller of Login screen therefore this issue occurs.
Your approach should be like as follows:
A) NavigationController -> SplashScreen -> LoginScreen
B) MainTabBarController -> MainNavigationController -> MainViewController -> DetailViewController
When user logged in, you should replace your window.rootViewController with B) MainTabBarController

#IBAction func addBasket(_ sender: Any) {
SingletonCart.sharedFood.food.append(food!)
self.navigationController?.popViewController(animated: true)
}

Related

Setting a viewController property by using a shared instance remains nil

I have two viewControllers:
1/ LoginViewController
2/ BibliothequeViewController
I am presenting BibliothequeViewController by clicking on a button inside LoginViewController and in the same time trying to communicate to BibliothequeViewController that it was LoginViewController that presented it.
So inside LoginViewController, I have this:
#IBAction func onLibrariesButtonClicked(_ sender: Any) {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc: BibliothequesViewController = storyboard.instantiateViewController(withIdentifier: "BibliothequesViewController") as! BibliothequesViewController
BibliothequesViewController.sharedInstance.presentedBy=self
print("INSIDE LoginViewController.onLibrariesButtonClicked, BibliothequesViewController.sharedInstance.presentedBy",BibliothequesViewController.sharedInstance.presentedBy!)
// Logs LoginViewController
self.present(vc, animated: true, completion: nil)
}
Inside BibliothequesViewController, I have this:
class BibliothequesViewController: UIViewController {
// presentedBy represents which view has presented the BibliothequesViewController
// So that when a library is selected, I go back to the ViewController that presented BibliothequesViewController
var presentedBy: UIViewController?
override func viewDidLoad() {
super.viewDidLoad()
print("INSIDE viewDidLoad, presentedBy: ",presentedBy)
// Logs nil
}
}
So as you see, in the LoginViewController code, BibliothequesViewController.sharedInstance.presentedBy has been set to LoginViewController.
But inside BibliothequeViewController, it is nil, when it should be LoginViewController.
I tried this:
print("INSIDE BibliothequesViewController, BibliothequesViewController.sharedInstance.presentedBy",BibliothequesViewController.sharedInstance.presentedBy!)
And I got LoginViewController logged. So I got what I needed.
But I expected the code above to work too.

Not navigate to specific view controller?

I am trying to navigate to specific view controller but it is not working.
what i am doing is below
var viewControllers:[UIViewController]!
var firstView : UIViewController!
let storyboard = UIStoryboard(name: "Main", bundle: nil)
firstView = storyboard.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
viewControllers = [firstView]
#IBAction func BackAction(_ sender: Any) {
for aViewController in viewControllers {
if aViewController is FirstViewController {
self.navigationController!.popToViewController(aViewController, animated: true)
}
}
}
but not working .
Please help me where i am wrong.
Thanks

How to push UIViewController in self.dismiss block?

There is HomeViewController as main viewController and LeftMenuViewController presented modally over current context. Now in LeftMenuViewController there is option to open ProfileViewController but I don't want to show ProfileViewController over LeftMenuViewController, So used this code but it is not working for some unknown reason, LeftViewController is dismissed but ProfileViewController is not pushed to front.
#IBAction func editAction(_ sender: Any) {
let homeVC:HomeViewController = self.presentingViewController!.childViewControllers[0] as! HomeViewController
self.dismiss(animated: false) {
DispatchQueue.global().async {
let infoVC:ProfileViewController = self.storyboard?.instantiateViewController(withIdentifier: "ProfileViewController") as! ProfileViewController
homeVC.navigationController?.pushViewController(infoVC, animated: true)
}
}
}
Any suggestion will be very helpfull
Change
DispatchQueue.global()
To
DispatchQueue.main
UI operations should be put in main queue

Swift ios check which viewcontroller is present

I wonder how I can check what view controller that is currently displayed.
When a user recivies a notification and press on it I want to take the user to a certain VC. But only if the user is not already there.
I am using this when I get a notification:
if let tabBarController = self.window!.rootViewController as? CustomTabBarController {
let navInTab:UINavigationController = tabBarController.viewControllers?[0] as! UINavigationController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationViewController = storyboard.instantiateViewController(withIdentifier: "EventVc") as? EventsViewController
navInTab.pushViewController(destinationViewController!, animated: true)
tabBarController.selectedIndex = 0
}
I dont want to run this code if the user already is in EventVc
Also, can I run the code above if the user already is in tab 0 but in a different VC than EventVc?
And if it is any help my app is built like this:
(root) TabBar
(tab1) -> navigation controller -> vc -> vc...
(tab2) -> navigation controller -> vc -> vc...
(tab3) -> navigation controller -> vc -> vc...
(tab4) -> navigation controller -> vc -> vc...
this function should solve your problem, just send index number as an argument (forexample: 0 for tab1, 1 for tab2 etc.) at it navigates you selectedIndex ViewController.
// Navigation TabIndex TabBar View Controller
fileprivate func goTabIndex(index: Int) {
let storyboard = UIStoryboard(name: "yourTabbarStoryboardID", bundle: nil)
let tabBarController = storyboard.instantiateViewController(withIdentifier: "EventVc") as! UITabBarController
tabBarController.selectedIndex = index
self.window?.makeKeyAndVisible()
DispatchQueue.main.async {
self.window?.rootViewController?.present(tabBarController, animated: false)
}
}
You can find the Presenting ViewController like this;
let presentingVC = self.window?.rootViewController?.presentingViewController
Presented ViewController;
let presentedVC = self.window?.rootViewController?.presentedViewController

Presenting VC embedded in a NavController from AppDelegate

I'm trying to want to present/push a VC embedded in a NavController from AppDelegate. I previously used this code but somehow it's not working anymore:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let VC = storyboard.instantiateViewControllerWithIdentifier("PendingRequest") as! PendingRequestVC
let navController = UINavigationController.self(rootViewController: VC)
let rootViewController = UIApplication.sharedApplication().keyWindow!.rootViewController
rootViewController!.presentViewController(navController, animated: false, completion: nil)
Other codes open my desired VC but not within a navigation pane. Any guidance would be appreciated.
Calling from AppDelegate after user interacts with push notification.
Edit:
I'm able to present the right VC by using this code:
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
if let viewController = mainStoryboard.instantiateViewControllerWithIdentifier("PendingNavController") as? UINavigationController {
if let yourViewController = viewController.topViewController as? PendingRequestVC {
//yourViewController.getRequestdata()
}
UIApplication.sharedApplication().keyWindow!.rootViewController = viewController;
}
But this code won't allow me to go back using the Close button on my NavBar.
My structure is as follow:
TabController -> NavController1 -> VC1 -> NavController1a -> VC1a
I'm trying to get to VC1a and be able to use the Closed button to go back to VC1
Add a UIButton in your presented ViewController's View. Following event will be performed by that button. You can dismiss your Navigation Controller this way
#IBAction func dismissViewController(sender: AnyObject) {
self.navigationController.dismissViewControllerAnimated(false, completion:nil);
}

Resources