Brecht Verhelst
Brecht Verhelst

Reputation: 91

Loading a new viewController on the same tab bar item not working

So I am having a problem loading a new view controller on the same tab bar item. I have a tab bar controller as my root controller and 4 tabs on the tab bar. One of which is the account tab, when the user is logged in he would need to see an overview of his account details but when there is no user there needs to be a sign-in / login page on that tab bar item. For the moment I have a custom tab bar class for my tabbarcontroller with a function that I thought was the solution but nothing happens. I have put a breakpoint in the view controller that needs to loaded (the user detail page) and it comes in the ViewDidLoad so it loads but it doesn't appear on the screen.

Hope I can finally solve this problem!

Kind regards B.

this is my custom tab bar controller class:

import UIKit

class TabBarViewController: UITabBarController, UITabBarControllerDelegate {
    var window: UIWindow?
    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self

    }


    func tabBarController(_ tabBarController: UITabBarController,
                          shouldSelect viewController: UIViewController) -> Bool{
        let frame = UIScreen.main.bounds
        window = UIWindow(frame: frame)
        let index = tabBarController.viewControllers?.firstIndex(of: viewController)
        if index == 3{ // Index of Account tab
            let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let loginVC = mainStoryBoard.instantiateViewController(withIdentifier: "MessagesViewController") as! MessagesViewController
            window?.rootViewController = loginVC
            window?.makeKeyAndVisible()
        }
        return true// you decide
    }
}


Upvotes: 1

Views: 1213

Answers (2)

Jawad Ali
Jawad Ali

Reputation: 14397

here is the code that presents full screen loginVc

func tabBarController(_ tabBarController: UITabBarController,
                          shouldSelect viewController: UIViewController) -> Bool{
        let frame = UIScreen.main.bounds
        window = UIWindow(frame: frame)
        let index = tabBarController.viewControllers?.firstIndex(of: viewController)
        if index == 1{ // Index of Account tab
            let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let loginVC = mainStoryBoard.instantiateViewController(withIdentifier: "MessagesViewController") as! MessagesViewController
            loginVC.modalPresentationStyle = .fullScreen
            self.present(loginVC, animated: false, completion: nil)
        }
        return true// you decide
    }

If you also want to have bottom bar ... your that viewController should be Navigation Controller and you can push your desired ViewController then like

func tabBarController(_ tabBarController: UITabBarController,
                          shouldSelect viewController: UIViewController) -> Bool{
        let frame = UIScreen.main.bounds
        window = UIWindow(frame: frame)
        let index = tabBarController.viewControllers?.firstIndex(of: viewController)
        if index == 1{ // Index of Account tab
            let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let loginVC = mainStoryBoard.instantiateViewController(withIdentifier: "MessagesViewController") as! MessagesViewController
           // loginVC.modalPresentationStyle = .fullScreen

            if let navigation = viewController as? UINavigationController {

                navigation.pushViewController(loginVC, animated: false)
            }
        }
        return true// you decide
    }

It will show back button and navigationBar on top if you dont want NavigationBar then in your MessagesViewController did load function call

override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.isNavigationBarHidden = true
        // Do any additional setup after loading the view.
    }

And if you just want to hide back button then call

override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.setHidesBackButton(true, animated: false);
        // Do any additional setup after loading the view.
    }

Upvotes: 1

elliott-io
elliott-io

Reputation: 1414

Changing your rootViewController is bad practice in Swift.

The correct way to handle tasks like this is to override your accountViewController's viewWillAppear function to determine if the user isn't logged in and present your loginViewController. Try something like:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // authManager would be a custom class that manages authorization with a property for loggedIn
    if authManager.loggedIn == false {
        guard let loginVC = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "login") as? LoginViewController else { return }
        self.present(loginVC, animated: true, completion: nil)
    }
}

Upvotes: 0

Related Questions