Swift 4: NavigationController Not Showing Bar on Subsequent Pages - ios

I embedded the LoginVC a NavigationController and on log-in, push the user to SwitchboardVC.
If the user is already logged in, I bypass the Login Screen with this code in the AppDelegate in didFinishLaunchingWithOptions:
if Auth.auth().currentUser != nil
{
let mainStoryBoard: UIStoryboard = UIStoryboard(name:"Main", bundle:nil)
let nextView: SwitchboardVC = mainStoryBoard.instantiateViewController(withIdentifier: "SwitchboardVC") as! SwitchboardVC
self.window?.rootViewController = nextView
}
When I have to login, the NavigationBar shows on all screens but if I am already logged in, the navigation bar is missing on all other screens.
I haven't been able to find a solution on Google yet but I am assuming that I am not searching for the correct term.
Any help is greatly appreciated

I believe it is because you are setting your root as the newView rather than pushing the newView from the navigationController, which would add it to the navigation stack and keep the bar at the top.
For the navigation hierarchy here is some reading:
https://medium.com/#strawb3rryx7/swift-the-hierarchy-of-uinavigationcontroller-programmatically-91631990f495

Related

Permanently Leave Navigation Controller in Xcode [duplicate]

This question already has answers here:
Change initial view controller after first launch of app
(2 answers)
Closed 5 years ago.
The starting point for my app is a simple login screen. If the user wants to make a new account, then they will segue into a navigation controller which manages all the views for creating a new account. The problem is that after they have made the account and signed in, the navigation bar is still there (pressing the back button will bring them to the "enter a password" page). I don't want to simply hide the navigation bar, I want the navigation controller and it's whole stack of views to be gone completely.
First of all after a successfull registration don't wait the user to click back or any thing automatically direct it to the main content VC of the app by changing the root of the AppDelegate's window to the mainVC embeded in a navigation controller , so later you can push other VCs to it like user settings , about VCs and so on
first create a new nav
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier :"mainView") as! mainViewController
let navController = UINavigationController.init(rootViewController: viewController)
and assign it to root
let appDelegate = UIApplication.shared.delegate as? AppDelegate
appDelegate?.window?.rootViewController = navController
You can Remove login screen from navigation controller using below code:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
var tempVCs = self.navigationController?.viewControllers
for tempVC: UIViewController in tempVCs {
// remove login screen from navigation stack
if (tempVC is LoginScreenVC) {
tempVC.removeFromParentViewController()
}
}
}

How to skip login screen from app delegate in tabbed bar App

I am trying to skip the login screen when I am close the app and relaunch again.
I got many answered questions but none of them with tabbed bar application.
So the challenge is I have many root view controllers which are distract my entire project if tried to assign a root directly with SecondViewController.
Here an image of my project:
https://imgur.com/a/YoUMf
is the tabbed bar app
navigation to index 0 tab bar
login screen
profile page
I want to skip login screen and show profile page direct since my:
if UserDefaults.standard.object(forKey: "USER_KEY_UID") != nil {
/*provide me the correct code can be applied here with out distracting the tabbed bar in the bottom */
}
Note: the code above I applied in appDelegete
Create a class for the tab bar controller. It should be sub class of UITabBarController
consider this as main view controller and add the login controller like below in your app delegate.
if UserDefaults.standard.object(forKey: "USER_KEY_UID") != nil {
let storyboard = UIStoryboard(name: [Main Stroyboard] , bundle: nil)
let mainVcIntial = storyboard.instantiateViewController(withIdentifier: [Main VC])
let mainController = UINavigationController(rootViewController: mainVcIntial)
window.rootViewController = mainController
}else{
let storyboard = UIStoryboard(name: [loginStoryboard] , bundle: nil)
let mainVcIntial = storyboard.instantiateViewController(withIdentifier: [Login VC])
let mainController = UINavigationController(rootViewController: mainVcIntial)
window.rootViewController = mainController
}
window.makeKeyAndVisible()

How to get navigation based template functionality in Swift programming

I need a navigation controller through out my project and my application has a social login initially. Once the authentication is verified user will be pushed to another view, where I display a tabbarcontroller having 2 tabs.
I don't know how to do this in Swift programming. I have embed my viewcontroller in Navigation controller, from here once the authentication is successful how do I push user to tabbar view? Tabbar should also have navigation.
I would like to replicate your idea into what I usually do in the following example.
This is how my storyboard looks like:
As you can see login/signup and Tab bar is not connected with any kind of Segue.
Here Sign in Navigation controller is setup of Initial Controller.
Assign This Navigation Controller an Storyboard ID(e.g.LoginNavigation):
Do the same with Tab Bar Controller, assign Storyboard ID(e.g. HomeTabBar)
Now, you just have to shuffle Root View Controller of the app between Login Nav and Tab Bar.
So if user successfully logs in, changes the application's root view to HomeTabBar using following code:
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let home: UITabBarController = storyboard.instantiateViewControllerWithIdentifier("HomeTabBar") as! UITabBarController
appDelegate.window?.rootViewController = home
And when user logs our, again change the root view to Login Nav:
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let entryPoint:UIViewController = mainStoryboard.instantiateViewControllerWithIdentifier("LoginNavigation")
appDelegate.window?.rootViewController = entryPoint
The appDelegate is defined in my constants.swift file :
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

Parse - Bypass Login in AppDelegate

I am working to bypass login screen if the current user is not nil. To do this, I followed the recommendation posted here. After running the code, I get a blank white view in the simulator without any errors showing. Here is the code:
storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle());
let currentUser = PFUser.currentUser()
print(currentUser)
if currentUser != nil {
self.window?.rootViewController = storyboard?.instantiateViewControllerWithIdentifier("HomeViewController");
}
Worth mentioning that HomeViewController is based on Tab navigation. What am I missing?
The setup I have is:
App is launched and the first view is the Sign In view (with button for signup). This initial view is SignInViewController and I embedded a UINavigationController to it.
User can login by providing credentials (if correct, segue is performed to redirect to HomeViewController)
User can signup and follow the steps (multiple controllers). At the end they will be redirected to Home View Controller.
I'm assuming your home tab bar controller has the identifier "HomeViewController" and your sign in view controller has the identifier "SignInViewController" and this code is in your didFinishLaunchingWithOptions() AppDelegate method:
storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
if let currentUser = PFUser.currentUser() { // currentUser is not nil
// set up app for valid in user
self.window?.rootViewController = storyboard?.instantiateViewControllerWithIdentifier("HomeViewController")
return true // don't load the rootViewController from your storyboard (if you have an initial view set)
} else { // there is no current user
// set up app for new or non logged in user
self.window?.rootViewController = storyboard?.instantiateViewControllerWithIdentifier("SignInViewController")
return true
}
From your comments, it sounds like you have a navigation controller with its root view controller being your sign in view controller, which is why when you segue to your tab bar controller, you get a navigation bar.
Since with my approach you're not getting the segue (and the sign in view controller's navigation bar), initialize a new UINavigationController and set its rootViewController to be your tab bar controller:
if let currentUser = PFUser.currentUser() { // currentUser is not nil
// load tab bar controller
let tabBarController = storyboard?.instantiateViewControllerWithIdentifier("TabBarViewController")
// initialize a new navigation controller with the tab bar controller as its rootViewController
let navC = UINavigationController(rootViewController: tabBarController)
// set the window's root view controller to be your new navigation controller
self.window?.rootViewController = navC
}
Can you give more information?
This is how I check if someone is already logged on
override func viewDidAppear(animated: Bool) {
let currentUser = PFUser.currentUser()
if currentUser != nil {
self.performSegueWithIdentifier("nameOfTheSegueIdentifier", sender: self)
}
}
Generally PFUser.currentUser() is not nil. You should use PFUser.currentUser().username. Use this code in your login/ signup ViewController (not AppDelegate (it works fine))
override func viewDidAppear(animated: Bool) {
if PFUser.currentUser().username != nil {
self.performSegueWithIdentifier("SEGUE", sender: self)
}
}
Two things to notice in this code: it is performed in the viewDidAppear method; not viewDidLoad. You cannot perform any segues until the view has appeared. Also, SEGUE is a temporary placeholder for your segue name. This segue should transfer the user over to the main page.
Note: the given code will show the login/signup viewcontroller's scene for about a second. I recommend putting a UIImageView on the ViewController that has the same frame as the view (covers the entire screen). If the username equals nil, you could put an else statement that says imageView.alpha = 0 (set the alpha to 1 in the viewDidLoad). Hope this helps.

iOS Switch between 2 Navigation controller

In my app, if the user isn't logged, it shows a login controller which is embedded in a navigation controller.
When the user is logged, the app should switch to the other navigation controller to display the app.
How can I switch from one navigation controller to another one when the user is logged. ?
Thanks
I'm checking if the user is log in app delegate :
// Check if user is log
let currentUser = PFUser.currentUser()
if currentUser != nil {
// Do stuff with the user
} else {
// Show the signup or login screen
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let nav = mainStoryboardIpad.instantiateViewControllerWithIdentifier("LogInController") as! UINavigationController
self.window?.rootViewController = nav
}
SOLUTION : looks like it works
When user press logIn button :
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let nav = mainStoryboardIpad.instantiateViewControllerWithIdentifier("MainNavController") as! UINavigationController
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window?.rootViewController = nav
Solution 1
One solution would be to use just a single navigation controller. When the user logs in, you would pop all the view controllers used for logging in and push main view controller on the stack.
Solution 2
Alternatively, you could present a new navigation controller modally on top of the login stuff, with main controller as its root. It would be simply presented on top of it.
Solution 3
You can also consider creating the navigation controller with main view controller first and presenting the login navigation controller on top of it. Then, when user logs in you would just dismiss the login navigation controller revealing the main view controller.
Set your navigation controller storyboard ID
let navigationController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SecondNavigationController")
self.presentViewController(navigationController, animated: true, completion: nil)
Hope this helps. :)

Resources