Search code examples
swiftuinavigationcontrolleruikituinavigationbar

Is it possible to have only large titles in the navigation bar?


I want my application to have large titles, however, when the user scrolls, I don't want the regular/normal navigation bar to appear. I just want the large bar to scroll up along with the tableview. Is this possible without making custom views in the navigation bar? I have done it successfully with custom views, but it isn't as fluid and putting a UISearchController inside is a pain.

func createNavController(vc: UIViewController, title: String, image: UIImage, tag: Int) -> UINavigationController {
    let navController = UINavigationController(rootViewController: vc)
    navController.navigationBar.prefersLargeTitles = true
    navController.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
    navController.navigationBar.shadowImage = UIImage()
    navController.navigationBar.tintColor = .headerColor
    navController.tabBarItem = UITabBarItem(title: title, image: image.withRenderingMode(.alwaysTemplate), tag: tag)
    navController.navigationBar.topItem?.title = title
    navController.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.headerColor, .font: UIFont.customHeaderFont(size: 25)]
    navController.navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.headerColor, .font: UIFont.customHeaderFont(size: 40)]
//        let titleLabel = UILabel()
//        titleLabel.text = title
//        titleLabel.textColor = .headerColor
//        titleLabel.font = UIFont.customHeaderFont(size: navController.navigationBar.frame.height - 5)
//        navController.navigationBar.addSubview(titleLabel)
//        titleLabel.anchor(top: nil, left: navController.navigationBar.leftAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 20, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
//        titleLabel.centerYAnchor.constraint(equalTo: navController.navigationBar.centerYAnchor).isActive = true
    return navController
}

Solution

  • Use my extension iOS 13 Swift 5 tested

    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
            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
        }
    }}
    

    How to use:

    configureNavigationBar(largeTitleColor: .yourColor, backgoundColor: .yourColor, tintColor: .yourColor, title: "yuorTitle", preferredLargeTitle: true)
    

    Set ViewController-based status bar...... to NO in info.plist if you want light Content

    If you don't want largeTitles set it to false

    for tranlsucent change navBarAppearance.configureWithOpaqueBackground() in:

    navBarAppearance.configureWithDefaultBackground()
    navigationController?.navigationBar.isTranslucent = true
    

    in the call set background color to .clear

    UPDATE: If you want to start with navigation controller and large Titles at first controller, don't forget to set launch controller in Scene Delegate like this:

    guard let windowScene = (scene as? UIWindowScene) else { return }
    window = UIWindow(windowScene: windowScene)
    window?.makeKeyAndVisible()
    let vC = UINavigationController(rootViewController: YourFirstViewController())
    window?.rootViewController = vC
    

    hope this help :)