Can't present view controller - swift

I have a function that checks if the user is logged in. If the user is not logged in I want to present a login view controller. But as I mentioned in the title, the view controller is not shown. In addition, the initial view controller is not the login view controller (which is set in a storyboard and is a tab bar view controller). In fact, that view controller is in a different storyboard. Is that the problem?
private func validateAuth(){
if FirebaseAuth.Auth.auth().currentUser == nil {
let storyboard = UIStoryboard(name: "LoginAndRegisterStoryboard", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "LoginViewController")
self.present(vc, animated: true, completion: nil)
}
}
I tried to set the breakpoint to the function. The debugger says that the function is executed but the view controller is not shown. Any solutions?
And yes, the function is called.

Related

How do I push a view controller in one case, but present it modally in another?

I have a view controller (VC3) that I want to push if accessed via one screen (VC1), but present it modally if accessed from a different screen (VC2). The destination view controller (VC3) is on its own storyboard and is embedded in a UINavigationController(which I believe is pretty important here).
In prepare(for segue) on VC1 I have this:
if let nav = segue.destination as? UINavigationController {
let destinationViewController = nav.topViewController as! LiftsViewController
destinationViewController.delegate = self
}
This presents the destination view controller (VC3) modally, which is what I want.
From VC2, the view controller (VC3) will be accessed by tapping on a cell in a table view so I want it pushed. But in prepare(for segue) on VC2 I have the same code as above because, well, I'm segueing to the same view controller which is in the UINavigationController.
I've looked at quite a few threads that address pushing vcs or presenting them modally, but can't find anything that answers how to do both with the same vc.
Thanks.
In this scenario let's not use the segue and push/present your VC's programmatically.
let vc3 = (UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LiftsViewController") as? LiftsViewController)!
vc3.delegate = self
now push:
self.navigationController?.pushViewController(vc3, animated: true)
or present:
self.presentViewController(vc3, animated: true, completion: nil)

How can I add a segue identifier to a programmatically modal transition?

I have a controller which is in the Main storyboard. When I click on a button, I call the displayBorneDetailsAction() action, it presents a modal view from another storyboard.
I would add a Segue identifier when I present my modal to pass data from my main view controller to my modal view controller (with prepareForSegue), but I don't know how to do it.
I tried to use performSegue(withIdentifier:), but it doesn't present the modal in the same way.
#IBAction func displayBorneDetailsAction(_ sender: Any) {
// open the modal of a borne
let storyboard : UIStoryboard = UIStoryboard(name: "Borne", bundle: nil)
let vc: BorneVC = storyboard.instantiateViewController(withIdentifier: "BorneVC") as! BorneVC
let navigationController = UINavigationController(rootViewController: vc)
navigationController.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
navigationController.edgesForExtendedLayout = []
self.present(navigationController, animated: true, completion: nil)
}
You cannot add an identifier to a programmatical segue, since you are able to access the instance of the controller that is being presented. Simply do anything you want with the controller in the function where you present it.

Open view controller programatically and dont see navigation bar. Swift 3

On my story board I have a collection view controller embedded in a navigation controller. Now from the cell of the collection view, I programaticly open the second view controller (called TwoPicsViewController), like this:
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "TwoPicsViewController") as! TwoPicsViewController
self.present(nextViewController, animated:true, completion:nil)
However when my TwoPicsViewController opens, I don't see the navigation bar at all. On the story board I connected the TwoPicsViewController to the first view controller with a segue show.
Am I missing something else?
Thanks
To push a new UIViewController to the navigation stack you should use:
self.navigationController?.pushViewController(nextViewController, animated: true)
Instead of:
self.present(nextViewController, animated:true, completion:nil)
You are not putting the new vc on the navigation stack, try this:
performSegue(withIdentifier: "Segue Name", sender: nil)
And on Storyboard select the Segue, attributes inspector, identifier = "Segue Name"

Swift viewWillAppear redirect

I'm using "viewWillAppear" to check UserDefaults.standard if i have data on the defaults i want redirect to Dashboard View and pass out of Login.
When i Log In correctly the app redirect normally but not in viewWillAppear in case of have data.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let defaults = UserDefaults.standard
if defaults.string(forKey: "username") != nil {
print("Exist")
print(defaults.string(forKey: "username")!)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "Dashboard")
self.present(vc, animated: true, completion: nil)
}
}
And i get this error con debug.
2016-11-04 17:44:32.130024 RHiOS[1155:278240] Warning: Attempt to present <RHiOS.MenuViewController: 0x100f0d480> on <RHiOS.ViewController: 0x100e0b880> whose view is not in the window hierarchy!
How can i redirect to Dash in case of have data? Thanks.
You cannot present a ViewController in viewWillAppear. Simply put this code in viewDidAppear and it should fix your problem.
When the view is not visible, it's not in the window hierarchy as the error mentioned. You could also create a segue in your storyboard and call performSegue(withIdentifier:sender:) instead.
You won't be able to present anything when the view hasn't appeared yet, so you either have to move your code into viewDidAppear or prevent this view from showing in the first place and redirect directly to the dashboard from a parent view controller that presents either the dashboard or login screen depending on whether or not you have data.

Presenting a a ViewController on a xib file in SWIFT

I have a xib file which I have created a pop up controller on a UIView. This pop up controller animates up when a button is pressed on a View Controller 1. I then have a button on the UIView which when pressed I want to present another View Controller (View Controller 2). code looks like:
class PopUpViewControllerSwift : UIViewController {
#IBAction func goToVC2(sender: UIButton) {
self.removeAnimate()
let VC2: VC2 = self.storyboard?.instantiateViewControllerWithIdentifier("VC2") as VC2
var modalStyle: UIModalTransitionStyle = UIModalTransitionStyle.CoverVertical
VC2.modalTransitionStyle = modalStyle
presentViewController(VC2, animated: true, completion: nil)
}
}
Although thou when the button is pressed it crashes, no error or callbacks or anything. Obviously this would normally work if it was just a regular View Controller but because I am doing it inside a pop Up View which has been animated on top of another View I think that is the problem?
Can anybody help?
thanks
I did this in a UICollectionView didSelectItemAtIndexPath method.
// Register Nib
let newViewController = NewViewController(nibName: "NewViewController", bundle: nil)
// Present View "Modally"
self.present(newViewController, animated: true, completion: nil)
I set the ID of the ViewController to the same as the file name so I would be sure to reference the right ViewController.
Make sure self.storyboard is not nil.
Also confirm that VC2 is one of the ViewController's identity in the storyboard file.
I hope it could help you.
if VC2 is in a storyboard file, try to use following command to get VC2
let storyboard = UIStoryboard(name: "YourStoryboardName(maybe 'Main')", bundle: nil)
let vc2 = storyboard.instantiateViewControllerWithIdentifier("VC2") as VC2
or if VC2 is in a nib file, try to use following command to get VC2
let vc2 = VC2(nibName: "YourNibName", bundle: nil)
It should be like this:
let vc = MyViewController(nibName: "MyViewController", bundle: nil)
present(vc, animated: true, completion: nil)