Present Pre-built FirebaseUI Authentication page - swift

I am using the Pre-built Firebase UI authentication for my swift project. The goal is to present the authentication page when the user clicks on the "user profile" button. Otherwise, the user doesn't have to register or sign in.
I have initialized a navigationController. So my initial thought was to simply push the Auth controller to my navigationController.
self.navigationController?.pushViewController(authUI.authViewController(), animated: true)
It failed with the error that no nested navigation controller is allowed as the authViewController() will return an instance of the initial navigation view controller of AuthUI.
My second thought was to simply call Window and set the rootViewController as the authViewController. Then just use the authViewController as the new navigation controller
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = authUI.authViewController()()
Unfortunately, it failed. Nothing showed up but a black screen.
The only way I figured is to call
self.present(authUI.authViewController(), animated: true, completion: nil)
However, the screen will be shown separately, which is not really what I want (see below)
Any thoughts/ideas/ suggestions are greatly appreciated.

I hope this can help you.
let authVC = authUI.authViewController()
authVC.modalPresentationStyle = .fullScreen
self.present(authVC, animated: true, completion: nil)
Thanks.

Related

UINAVIGATIONCONTROLLER doesn't show back button, doesn't do swipe to back: UIKIT

Hey Guys I am trying to use NavigationController for back button and swipe left to back action.
can you tell me what I am doing wrong ?
Could u tell me what else to do ?
P.S. Show instead of present doesn't work as well.
let vc = UINavigationController(rootViewController: BarcodeViewController())
vc.modalPresentationStyle = .fullScreen
present(vc, animated: false)
I did solve this problem by embedding main ViewController in SceneDelegate and then push a new viewController via UINavigationController.pushViewController ..

View on View controllers are all square shaped on Xcode 11, how?

I have tried to change it's size manually (by dragging) and still not working.
You can set its Content size to whatever you want.
On iOS 13 a "Modal" segue will show the presenting controller that way by default.
If you want the view controller to occupy the whole screen, set "Full Screen" on the "presentation" setting of any segue entering that controller.
Segue Settings
If your view presents programmatically (not via storyBoard), have this in mind:
From XCode 11 and up, when you build for iPad you have to add "modalPresentationStyle = .fullScreen" to get full screen views, not square ones. As follows:
let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen
self.present(vc, animated: true, completion: nil)
If you want transparency on the new viewController, you can write ".overFullScreen", as follows:
let vc = UIViewController()
vc.modalPresentationStyle = .overFullScreen
self.present(vc, animated: true, completion: nil)

How to present unique UITabBarControllers in Swift

I'm working on a project that has two different UITabBarControllers to represent two different states of the app. I can set the first UITabBarController once a user logs in and present the second when a button is pressed. However, I'm getting odd behavior when navigating within the second UITabBarController.
This is how I set the main tab bar.
let mainTabBar = MainTabBarController()
let mainMode = UINavigationController(rootViewController: mainTabBar)
UIApplication.shared.keyWindow?.rootViewController = mainMode
I use an identical method to navigate to the second tab bar.
let secondaryTabBar = SecondaryTabBarController()
let hiddenMode = UINavigationController(rootViewController: secondaryTabBar)
UIApplication.shared.keyWindow?.rootViewController = hiddenMode
However, when using the secondary UITabBarController, I see views from the main UITabBarController when navigating to an AVCaptureSession. More specifically, I see the last view (from which the secondaryTabBar is set) from the mainTabBar under the modal presentation of the capture session. Here's the problem point:
let captureSession = CameraViewController()
navigationController?.present(captureSession, animated: true, completion: nil)
I changed the modalPresentationStyle of the CameraViewController to .overCurrentContext and that solved the issue. Got it from here: Transparent background for modally presented viewcontroller

Cant dismiss view controller after present it

After presenting a Tab bar controller, I can't dismiss tab bar controller.
I also can't even tap my button after I reinstall without delete the app. Need to uninstall and reinstall the app then I am able to tap the button
I already tried some other way of dismiss the tab bar controller but still unable to dismiss the controller.
This is my current way to present controller after login
let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
let loginVC = storyboard.instantiateViewController(withIdentifier: "Home")
self.present(loginVC, animated: true, completion: nil)
This is my current way to dismiss controller
#IBAction func btnLogout_TouchUpInside(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
This is my root view
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
if defaults.bool(forKey: "isLoggedIn") {
// Show Home screen
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: "Home")
} else {
// Show Login screen
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: "Login")
}
window?.makeKeyAndVisible()
try to dismiss all presented controller it may work for you
DispatchQueue.main.async {
self.view.window!.rootViewController?.dismiss(animated: true, completion: {
print("All controller dismissed successfully..")
})
}
Try This
self.presentingViewController?.dismiss(animated: true, completion: nil)
Hmm. Your update helps although I'm still not sure what's happening. My guess is that you are setting login as root, then presenting home. But I'm not sure where or what you are trying to dismiss. If it's on the login then there is nothing to dismiss as it's the root view controller.
My suggestion would be to reconfigure the storyboard. Because you are manually presenting the view controllers I'm going to assume that the storyboard doesn't contain any segues between the controllers. I'd suggest adding the segues and using them.
I'd set the home view controller as the initial view controller and set the Main storyboard as the storyboard to load in the apps settings. Then all the code to load the storyboard and set the root view controller can be removed.
Next I'd make a manual modal segue from the home view controller to the login view controller. Then in the viewDidAppear of the home view controller I'd add the code to decide if a login was needed and to them perform the login segue.
Then in the login view controller you can do a dismiss and it will remove the model login view.
This is but one of many ways to do this, but it's pretty much the simplest to get you going. You don't need any code to load or set root view controllers or anything else. It just lets the storyboard do the work for you.

Swift - UITabBarContorller Initial View - when to force launch login screen?

I have programatically set up a custom UITabBarControler with three tabs, each of which is a UIViewController embedded a UINavigationController.
I am not using storyboards. I set the custom tab controller as the root in AppDelegate
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = CustomTabBarController()
The app runs fine and I get the three tabs and can move between them.
sample of how tabs are populated (in viewDidLoad of the customer tab bar controller)
let ordersVC = OrdersViewController() // where Orders is a UIViewController
ordersVC.title = "Orders"
ordersVC.view.backgroundColor = UIColor.white
let ordersVCNavi = UINavigationController(rootViewController: ordersVC)
ordersVCNavi.navigationBar.tintColor = UIColor.black
...
viewControllers = [homeVCNavi, inventoryVCNavi, ordersVCNavi]
Now I need to first to see if the user is logged in (using Firebase). I can easily check for already logged in (Firebase cached) or not logged in.
I do this logged in check in AppDelegate
My problem is when I need to force a login (jump to login view controller). I can not find a place that works.
- tried placing the call in the custom UITabBarController didLoad and the code is ignored
- tried placing the call in the didLoad and the willAppear in the initial tab controller also ignored
I can place a button on the initial tab and that button will indeed launch the login controller. So I can get to the login controller from a button press.
upon pressing a button I can execute this code and the login controller will show
let vc = LoginViewController()
self.navigationController?.pushViewController(vc, animated: false)
But if I know I need to force login and I try to do that same code snip above in viewDidLoad() or viewWillAppear() in the initial tab controller, or in the custom UITabBarController then the push is ignored. Nothing happens.
What is best practice for forcing login screen when initial view is tabbarcontroller?
Where should one put the navigation to the login controller to force login when not already logged in. Want to go to login so that user can not use the app if not logged in.
in didFinishLaunchingWithOptions
if loggedIn {
window?.rootViewController = CustomTabBarController()
}
else {
window?.rootViewController = LoginViewController()
}
after your login is successful
UIApplication.shared.keyWindow?.rootViewController = CustomTabBarController()