Reputation: 33
I am building an authentication system using the Firebase prebuilt UI, and I want to customize the UI to fit the program. Say I want to set the background color to black and change the corner radius of the buttons, is there any way I can do this? I've tried sub-classing the authPickerViewController
but somehow it didn't work. I did some searching, but couldn't find any tutorial or recent problems related to this either.
Here's what I have in my MainViewController
class LoginViewController: UIViewController, FUIAuthDelegate{
override func viewDidLoad() {
super.viewDidLoad()
let authUI = FUIAuth.defaultAuthUI()
authUI?.delegate = self
let providers: [FUIAuthProvider] = [
FUIEmailAuth(),
FUIGoogleAuth(),
FUIPhoneAuth(authUI:FUIAuth.defaultAuthUI()!)]
authUI?.providers = providers
let authViewController = authUI?.authViewController()
authViewController!.modalPresentationStyle = .fullScreen
authViewController!.setNavigationBarHidden(true, animated: false)
self.present(authViewController!, animated: false, completion: nil)
}
func application(_ app: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
let sourceApplication = options[UIApplicationOpenURLOptionsKey.sourceApplication]
if FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication as? String) ?? false {
return true
}
return false
}
}
And here is the subclass I created:
class FUICustomAuthPickerViewController: FUIAuthPickerViewController,FUIAuthDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .black
}
func authPickerViewController(forAuthUI authUI: FUIAuth) -> FUIAuthPickerViewController {
return FUICustomAuthPickerViewController(nibName: "FUICustomAuthPickerViewController",
bundle: Bundle.main,
authUI: authUI)
}
}
On the Firebase documentation for customization, they say that:
You can customize the sign-in screens by subclassing FirebaseUI's view controllers and specifying them in FUIAuth's delegate methods.
I am a beginner, how can I do that?
Edited:
So by following the instructions on this link I managed to add stuff to the pre-built UI by creating an extension to the FUIAuthDelegate
.
extension LoginViewController:FUIAuthDelegate {
func application(_ app: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
let sourceApplication = options[UIApplicationOpenURLOptionsKey.sourceApplication]
if FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication as? String) ?? false {
return true
}
return false
}
func authPickerViewController(forAuthUI authUI: FUIAuth) -> FUIAuthPickerViewController {
let vc = FUIAuthPickerViewController(authUI: authUI)
let view = UIView(frame: .zero)
view.backgroundColor = .black
view.translatesAutoresizingMaskIntoConstraints = false
vc.view.addSubview(view)
NSLayoutConstraint.activate([
view.heightAnchor.constraint(equalTo: vc.view.heightAnchor, multiplier: 1),
view.widthAnchor.constraint(equalTo: vc.view.widthAnchor, multiplier: 1)])
return vc
}
}
Turns out subclass is not necessarily needed. However, I can't seem to make this view I created to be the background, it either covers everything or nothing at all.I tried changing the background color of the view directly, didn't work. Anyone knows how to do this?
Upvotes: 1
Views: 1505
Reputation: 33
Solved the problem using the method and one of the comments provided in this link. Turns out, apart from subclassing, you have to add the following two methods to your subclass for it to work.
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?, authUI: FUIAuth?) {
super.init(nibName: nil, bundle: Bundle.main, authUI: authUI!)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
However, the approach I used (not sure if other approaches raise the same problem) also caused another problem - the email sign-in button stopped responding - which is addressed in this link by presenting the view controller with a navigationViewController
because the email sign-in button works together with the navigation bar, you can get rid of it once you have presented the view with a navigationViewController
.
Now the complete subclass looks like this:
import UIKit
import FirebaseUI
class FUICustomAuthPickerViewController: FUIAuthPickerViewController {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?, authUI: FUIAuth?) {
super.init(nibName: nil, bundle: Bundle.main, authUI: authUI!)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
let width = UIScreen.main.bounds.size.width
let height = UIScreen.main.bounds.size.height
let imageViewBackground = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
imageViewBackground.backgroundColor = .eatstrOrange
view.insertSubview(imageViewBackground, at: 0)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(false, animated: animated)
}
}
And here's the main view controller:
import UIKit
import FirebaseUI
class LoginViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
let authUI = FUIAuth.defaultAuthUI()
let delegate = authUI?.delegate
authUI?.delegate = delegate
let providers: [FUIAuthProvider] = [
FUIGoogleAuth(),
FUIEmailAuth(),
FUIPhoneAuth(authUI:FUIAuth.defaultAuthUI()!)]
authUI?.providers = providers
let authViewController = FUICustomAuthPickerViewController(authUI: authUI!)
authViewController.modalPresentationStyle = .fullScreen
navigationController?.pushViewController(authViewController, animated: false)
}
}
Upvotes: 2