I have a problem that is taking me time to solve... It is about the way my UITabBarController class interacts with the rest of the view controllers it owns.
This is what I have thought for my application. I don't know if it is the most convenient, that's why I ask for help.
First. In my Scene delegate i have:
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
window?.rootViewController = TabBar()
*TabBar is my Custom Class of UITabBarController.
My goal is to have a User type that updates in all view controllers when a function that requires it is called.
I've tried addchild and protocols from TabBar() but I haven't been able to set it correctly.
basic scheme
Sorry for so much text, but I wanted to explain it in the best possible way.
I attach some code.
Thanks for the help!
class TabBar: UITabBarController {
private var user: User?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
UITabBar.appearance().backgroundColor = .white
UITabBar.appearance().unselectedItemTintColor = .lightGray
tabBar.tintColor = .black
fetchUserData()
}
func fetchUserData() {
print("hey")
guard let currentUid = Auth.auth().currentUser?.uid else { return }
Service.shared.fetchUserData(uid: currentUid) { user in
self.user = user
self.setupVCs()
}
}
func setupVCs() {
guard let user = self.user else { return }
viewControllers = [
createNavController(for: HomeController(user: user), title: NSLocalizedString("Pedidos", comment: ""), image: UIImage(named: "pedidos")!),
createNavController(for: SignUpController(), title: NSLocalizedString("Mapa", comment: ""), image: UIImage(named: "location")!),
createNavController(for: InformePeriodos(user: user), title: NSLocalizedString("Ganancias", comment: ""), image: UIImage(named: "euro")!),
createNavController(for: RetirarEfectivo(user: user), title: NSLocalizedString("Agenda", comment: ""), image: UIImage(named: "calendar")!),
createNavController(for: PerfilController(user: user), title: NSLocalizedString("Perfil", comment: ""), image: UIImage(named: "person")!)
]
}
fileprivate func createNavController(for rootViewController: UIViewController,title: String,image: UIImage) -> UIViewController {
let navController = UINavigationController(rootViewController: rootViewController)
navController.tabBarItem.title = title
navController.tabBarItem.image = image
return navController
}
}
Here my Profile controller button action
@objc func confirmar(){
//efectivo, and gP and retiro are some data
DriverService.shared.updateRetiro(efectivo: saldoEfectivo, gP: gananciasPagadas, retiro: doubleinputValue) {
guard let currentUid = Auth.auth().currentUser?.uid else { return }
Service.shared.fetchUserData(uid: currentUid) { user in
self.user = user
self.configureUI()
//i need to call FETCHUSERDATA FROM MY TABBAR HERE?
self.removeSpinner()
}
}
}
i think that call fetchuserdata in my profileController can resolve part of the problem
I post the solution if helps everyone with same issue
import UIKit
import Firebase
import CoreLocation
class TabBar: UITabBarController {
private var user: User?
override func viewDidLoad() {
super.viewDidLoad()
self.overrideUserInterfaceStyle = .light
fetchUserData()
let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(updateUser), name: NSNotification.Name(rawValue: "updateUser"), object: nil)
}
@objc func updateUser() {
print("updateUser")
guard let currentUid = Auth.auth().currentUser?.uid else { return }
Service.shared.fetchUserData(uid: currentUid) { user in
self.user = user
self.setupVCs()
}
}
// MARK: - Helper Functions
func fetchUserData() {
print("hey")
guard let currentUid = Auth.auth().currentUser?.uid else { return }
Service.shared.fetchUserData(uid: currentUid) { user in
self.user = user
self.setupVCs()
}
}
func setupVCs() {
guard let user = self.user else { return }
viewControllers = [
createNavController(for: HomeController(user: user), title: NSLocalizedString("Pedidos", comment: ""), image: UIImage(named: "pedidos")!),
createNavController(for: RiderMap(user: user), title: NSLocalizedString("Mapa", comment: ""), image: UIImage(named: "location")!),
createNavController(for: InformePeriodos(user: user), title: NSLocalizedString("Ganancias", comment: ""), image: UIImage(named: "euro")!),
createNavController(for: CalendarController(user: user), title: NSLocalizedString("Agenda", comment: ""), image: UIImage(named: "calendar")!),
createNavController(for: PerfilController(user: user), title: NSLocalizedString("Perfil", comment: ""), image: UIImage(named: "person")!)
]
}
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
fileprivate func createNavController(for rootViewController: UIViewController,
title: String,
image: UIImage) -> UIViewController {
let navController = UINavigationController(rootViewController: rootViewController)
navController.tabBarItem.title = title
navController.tabBarItem.image = image
return navController
}
}
And then... the function that send notification to this tabbar from other view controller (without delegates)
@objc func updateUser(){
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateUser"), object: nil)
}