'How to configure multiple view controllers to your main tab view controller

I am having issues configuring various view controllers to my main tab controller. After login I see a blank screen. This is partially due to my view controllers not being able to configure to the tab bar controller. I thought calling fetchUsers() and fetchDiscover() in the viewDidLoad would fix this issue. But, it seems to be a bit deeper than that. Maybe the issue is where I am declaring the variables user? and discover?. I just cant seem to figure it out. I would appreciate your ideas on how to solve this issue. Thank you in advance.

import UIKit
import Firebase
import YPImagePicker
import AVFoundation
import DropDown

class MainTabController: UITabBarController {
   
    // MARK: - Lifecycle
    
    var user: User?  {
        didSet {
            guard let user = user else { return }
            guard let discover = discover else { return }
            configureViewControllers(withUser: user, withDiscover: discover)
        }
    }
    
    var discover: Discover? {
        didSet {
        guard let discover = discover else { return }
        guard let user = user else { return }
    configureViewControllers(withUser: user, withDiscover: discover)
    }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        checkIfUserIsLoggedIn()
        fetchUser()
        fetchDiscover()
        
    }
    //MARK: - Labels
    class MyCell: DropDownCell {
    
        let postLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 12)
        label.textColor = .black
        label.text = "Post"
        let tap = UITapGestureRecognizer(target: self, action: #selector(pushToSelectDiscoverController))
        label.isUserInteractionEnabled = true
        label.addGestureRecognizer(tap)
        return label
    }()
    
    let discoverLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 12)
        label.textColor = .black
        label.text = "Community"
        let tap = UITapGestureRecognizer(target: self, action: #selector(pushToImagePicker))
        label.isUserInteractionEnabled = true
        label.addGestureRecognizer(tap)
        return label
    }()
    
    }
    // MARK: - API
    func fetchUser() {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        guard let discoverId = Auth.auth().currentUser?.uid else { return }
        UserService.fetchUser(withUid: uid, withDiscoverId: discoverId) { user,discover in
            self.user = user
            self.discover = discover
        }
    }
    
    func fetchDiscover() {
        guard let discoverId = Auth.auth().currentUser?.uid else { return }
    
        DiscoverService.fetchDiscover(withdiscoverId: discoverId) { discover, user in
            self.discover = discover
        }
    }
    
    func checkIfUserIsLoggedIn() {
        if Auth.auth().currentUser == nil {
            DispatchQueue.main.async {
                let controller = LoginController()
                controller.delegate = self
                let nav = UINavigationController(rootViewController: controller)
                nav.modalPresentationStyle = .fullScreen
                self.present(nav, animated: true, completion: nil)
            }
        }
    }
    
    
    // MARK: - Helpers
    func configureViewControllers(withUser user: User, withDiscover discover: Discover) {
        view.backgroundColor = .white
        self.delegate = self
        
        let layout = UICollectionViewFlowLayout()
        let discoverFeed = templateNavigationController(unselectedImage: #imageLiteral(resourceName: "Image-29"), selectedImage: #imageLiteral(resourceName: "Image-30"), rootViewController: DiscoverFeedController(collectionViewLayout: layout))
        
        let search = templateNavigationController(unselectedImage: #imageLiteral(resourceName: "search_unselected"), selectedImage: #imageLiteral(resourceName: "search_selected"), rootViewController: SearchController(config: .all, discConfig: .all))
        
        let imageSelector = templateNavigationController(unselectedImage: #imageLiteral(resourceName: "plus_unselected"), selectedImage: #imageLiteral(resourceName: "plus_unselected"), rootViewController: ImageSelectorController(currentUser: user))
        
    let notifications = templateNavigationController(unselectedImage: #imageLiteral(resourceName: "Image-37"), selectedImage: #imageLiteral(resourceName: "Image-36"), rootViewController: NotificationsController())
        
        let profileController = ProfileController(user: user, discover: discover)
        
        let profile = templateNavigationController(unselectedImage: #imageLiteral(resourceName: "profile_unselected"), selectedImage: #imageLiteral(resourceName: "profile_selected"), rootViewController: profileController)
        
        viewControllers = [discoverFeed, search, imageSelector, notifications, profile]
        
        tabBar.tintColor = .black
    }
    
    func templateNavigationController(unselectedImage: UIImage, selectedImage: UIImage, rootViewController: UIViewController) -> UINavigationController {
        let nav = UINavigationController(rootViewController: rootViewController)
        nav.tabBarItem.image = unselectedImage
        nav.tabBarItem.selectedImage = selectedImage
        nav.navigationBar.tintColor = .black
        return nav
    }
    

    func didFinishPickingMediaForDiscover(_ picker: YPImagePicker) {
        picker.didFinishPicking { items, _ in
            picker.dismiss(animated: false) {
                guard let discoverImage = items.singlePhoto?.image else { return }
                let controller = UploadDiscoverController()
                controller.discoverImage = discoverImage
                controller.delegate = self
                controller.currentUser = self.user

                let nav = UINavigationController(rootViewController: controller)
                nav.modalPresentationStyle = .fullScreen
                self.present(nav, animated: false, completion: nil)
            }
        }
    }
    
    func didFinishPickingMedia(_ picker: YPImagePicker) {
        picker.didFinishPicking { items, _ in
            picker.dismiss(animated: false) {
                guard let selectedImage = items.singlePhoto?.image else { return }
                
                let controller = UploadPostController()
                controller.selectedImage = selectedImage
                controller.delegate = self
                controller.currentUser = self.user

                let nav = UINavigationController(rootViewController: controller)
                nav.modalPresentationStyle = .fullScreen
                self.present(nav, animated: false, completion: nil)
            }
        }
    }
    
 }

// MARK: - AuthenticationDelegate

extension MainTabController: AuthenticationDelegate {
    func authenticationDidComplete() {
        fetchUser()
        self.dismiss(animated: true, completion: nil)
    }
}

// MARK: - UITabBarControllerDelegate

extension MainTabController: UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        
        let index = viewControllers?.firstIndex(of: viewController)
        
    if index == 2 {
        dropDownMenu().self
        }
        
        return true
    }
}




extension MainTabController: UploadPostControllerDelegate {
    func controllerDidFinishUploadingPost(_ controller: UploadPostController) {
        selectedIndex = 0
        controller.dismiss(animated: true, completion: nil)

        guard let feedNav = viewControllers?.first as? UINavigationController else { return }
        guard let feed = feedNav.viewControllers.first as? FeedController else { return }
        feed.handleRefresh()
    }
}



extension MainTabController: UploadDiscoverControllerDelegate {
    func controllerDidFinishUploadingDiscover(_ controller: UploadDiscoverController) {
        selectedIndex = 0
        controller.dismiss(animated: true, completion: nil)
        guard let discoverFeedNav = viewControllers?.first as? UINavigationController else { return }
        guard let discoverFeed = discoverFeedNav.viewControllers.first as? DiscoverFeedController else { return }
    }
}




extension MainTabController {
    func dropDownMenu() {
        let  dropDown = DropDown(frame: CGRect(x: 110, y: 140, width: 30, height: 30))
       
        dropDown.anchorView = tabBar
        dropDown.dataSource = ["Post", "Discover"]
        dropDown.direction = .top
        dropDown.dismissMode = .automatic
        dropDown.cellNib = UINib(nibName: "MyCell", bundle: nil)

        dropDown.customCellConfiguration = { (index: Index, item: String, cell: DropDownCell) -> Void in
           guard let cell = cell as? MyCell else { return }

            cell.discoverLabel.isUserInteractionEnabled = true
            cell.postLabel.isUserInteractionEnabled = true
    }
}
}

extension MainTabController {
    @objc func pushToImagePicker() -> Bool {
    
        
            var config = YPImagePickerConfiguration()
            config.library.mediaType = .photo
            //config.library.mediaType = .video
            config.shouldSaveNewPicturesToAlbum = false
            config.startOnScreen = .library
            config.screens = [.library]
            config.hidesStatusBar = false
            config.hidesBottomBar = false
            config.library.maxNumberOfItems = 5

            let picker = YPImagePicker(configuration: config)
            picker.modalPresentationStyle = .fullScreen
            present(picker, animated: true, completion: nil)

            didFinishPickingMedia(picker)

            return true
        
    }
    

}

extension MainTabController {
    @objc func pushToSelectDiscoverController() {
        
        SelectDiscoverService.showSelectDiscover(toUid: user?.uid, fromDiscover: discover, fromUser: user) { discover in
            let controller = SelectDiscoverController(user: self.user, discover: discover)
            self.navigationController?.pushViewController(controller, animated: true)
            
        }
}
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source