Search code examples
iosswiftxcodeuitabbarcontrolleruinavigationbar

Navigation Bar Large Title Problem on some View's


I'm developing an iOS app, I created some view with TabBar Controller, and I want to use Large Navigation Bar on some View's.

I have three VC on TabBar Controller :

  • FeedVC
  • ChatsVC
  • ProfilesVC

I will use normal Navigation Bar on ( FeedVC ), and I will use Large Navigation Bar on ( ChatsVC, ProfilesVC ).

the problem is when I tap the ChatsVC from FeedVC, it show normal NavigationBar until I scroll down, but when I tap ChatsVC from ProfilesVC is shows Large.

Here is a recorded video of that : Video uploaded to my CDN

The code I use on FeedVC :

    override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    self.tabBarController?.navigationController?.navigationBar.prefersLargeTitles = false
    self.tabBarController?.title = "Feed"
}

override func viewDidDisappear(_ animated: Bool) {
    self.tabBarController?.navigationController?.navigationBar.prefersLargeTitles = true
}

Solution

  • Programmatically Way, configure Your tab bar controller like this and hide tabBar navigation bar:

    class TabBarCobtroller: UIViewController {
    
    let yourTabBar = UITabBarController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        yourTabBar.tabBarController?.tabBar.isHidden = true // hide the navigation bar of the tab bar
        yourTabBar.tabBar.tintColor = UIColor.black
        createTabBarController()
    }
    
    func createTabBarController() {
        
        let firstVc = FirstVCController()
        firstVc.tabBarItem = UITabBarItem.init(title: "Home", image: UIImage(systemName: "house.fill"), tag: 1)
        
        let secondVc = SecondVcController()
        secondVc.tabBarItem = UITabBarItem.init(title: "Chats", image: UIImage(systemName: "heart.fill"), tag: 1)
        
        let thirdVc = ThirdViewController()
        thirdVc.tabBarItem = UITabBarItem.init(title: "Profile", image: UIImage(systemName: "person.fill"), tag: 1)
        
        let controllerArray = [firstVc, secondVc, thirdVc]
        yourTabBar.viewControllers = controllerArray.map{ UINavigationController.init(rootViewController: $0)}
        
        self.view.addSubview(yourTabBar.view)
     }
    }
    

    Now add this extension for custom navBar:

    extension UIViewController {
    func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
        if #available(iOS 13.0, *) {
            let navBarAppearance = UINavigationBarAppearance()
            navBarAppearance.configureWithOpaqueBackground()
            navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
            navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
            navBarAppearance.backgroundColor = backgoundColor
            
            navigationController?.navigationBar.standardAppearance = navBarAppearance
            navigationController?.navigationBar.compactAppearance = navBarAppearance
            navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
            
            navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
            navigationItem.largeTitleDisplayMode = .always
            navigationController?.navigationBar.isTranslucent = false
            navigationController?.navigationBar.tintColor = tintColor
            navigationItem.title = title
            
        } else {
            // Fallback on earlier versions
            navigationController?.navigationBar.barTintColor = backgoundColor
            navigationController?.navigationBar.tintColor = tintColor
            navigationController?.navigationBar.isTranslucent = false
            navigationItem.title = title
        }
      }
    }
    

    After that in your FeedVC configure in viewWillAppear your custom nav bar with normal title for this controller:

    coverride func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        configureNavigationBar(largeTitleColor: .white, backgoundColor: .red, tintColor: .white, title: "FeedVC", preferredLargeTitle: false)
    }
    

    for chatsVC with Large title:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        configureNavigationBar(largeTitleColor: .white, backgoundColor: .red, tintColor: .white, title: "ChatsVC", preferredLargeTitle: true)
    }
    

    For profile with large title:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        configureNavigationBar(largeTitleColor: .white, backgoundColor: .mediumBlue, tintColor: .white, title: "ProfilesVC", preferredLargeTitle: true)
    }
    

    now you have control of your bar, just edit the line:

    configureNavigationBar(largeTitleColor: .yourColor, backgoundColor: .yourColor, tintColor: .yourColor, title: "YourVCName", preferredLargeTitle: true) // true if you want large title or falsa if you want normal title...
    

    This is the result:

    enter image description here