Search code examples
swiftswift5

Swift 5.6 NavigationItem does not show


I am trying to add ImageView to NavigationBar. I did all setups in SceneDelegate to setup a rootviewcontroller and seems like it works, but when I try to add Title or Image it does no show it.

SceneDelegate :

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let scene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: scene)
        window?.rootViewController = UINavigationController(rootViewController: MainTabController())
        window?.makeKeyAndVisible()
    }

NavigationBar NavigationController:

class FeedController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        configureUI()
        setupNavController()
    }
    
    func configureUI() {
        view.backgroundColor = .white

        let imageView = UIImageView(image: UIImage(named: "twitter_logo_blue"))
        imageView.contentMode = .scaleAspectFit
        navigationItem.titleView = imageView
   
    }
    
    @objc func addTapped() {
        //
    }
    
    func setupNavController() {
        if #available(iOS 15.0, *) {
            let navigationBarAppearance = UINavigationBarAppearance()
            navigationBarAppearance.configureWithDefaultBackground()
            UINavigationBar.appearance().standardAppearance = navigationBarAppearance
            UINavigationBar.appearance().compactAppearance = navigationBarAppearance
            UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance
        }
    }
}

Solution

  • Do not embed UITabBarController in UINavigationController. Rather embed each UIViewController into UINavigationController before adding them to UITabBarController. Here is an example.

    Modify the scene(_:willConnectTo:options) method like below.

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = MainTabViewController()
        self.window = window
        window.makeKeyAndVisible()
    }
    

    Here is the MainTabBarController class.

    class MainTabViewController: UITabBarController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let mainVC = UINavigationController(rootViewController: ViewController())
            mainVC.tabBarItem = UITabBarItem(title: "Tab 1", image: UIImage(systemName: "circle"), selectedImage: UIImage(systemName: "circle.fill"))
            let secondVC = UINavigationController(rootViewController: SecondViewController())
            secondVC.tabBarItem = UITabBarItem(title: "Tab 2", image: UIImage(systemName: "square"), selectedImage: UIImage(systemName: "square.fill"))
            
            viewControllers = [mainVC, secondVC]
        }
    }
    

    Now modify titleView of navigationItem in UIViewController.

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            configureUI()
            setupNavController()
        }
        
        func configureUI() {
            view.backgroundColor = .white
            
            let imageView = UIImageView(image: UIImage(systemName: "sun.max.circle.fill"))
            imageView.contentMode = .scaleAspectFit
            navigationItem.titleView = imageView
            
        }
        
        func setupNavController() {
            if #available(iOS 15.0, *) {
                
                let navigationBarAppearance = UINavigationBarAppearance()
                navigationBarAppearance.configureWithDefaultBackground()
                UINavigationBar.appearance().standardAppearance = navigationBarAppearance
                UINavigationBar.appearance().compactAppearance = navigationBarAppearance
                UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance
            }
        }
    }