1

I'm trying to create a custom nav bar and want to add a title on the left and a chat icon on the right.

Just like this

but it's not showing any item. The background color is the only custom that working.

I'm calling it like this

let garageVC = HomeNavController(rootViewController: GarageRouter.assembleModule(), title: "My Garage")

My Nav class

import UIKit

class HomeNavController: UINavigationController {
    
    var tabTitle: String?
    
    init(rootViewController: UIViewController, title: String) {
        super.init(rootViewController: rootViewController)
        self.tabTitle = title
        configure()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configure()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        configure()
    }
    
    private func configure() {
        
        navigationBar.isHidden = false
        navigationBar.isTranslucent = false

        navigationBar.tintColor = .white
        navigationBar.barTintColor = .primary
        
        let nameLabel = UILabel(frame: .zero)
        nameLabel.textColor = .white
        nameLabel.tintColor = .white
        nameLabel.text = tabTitle
        navigationItem.leftBarButtonItem = UIBarButtonItem(customView: nameLabel)

        
        let chatButton = UIButton(type: .system)
        chatButton.setImage(UIImage(named: "home-chat")?.withRenderingMode(.alwaysOriginal), for: .normal)
        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: chatButton)
        chatButton.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: 0, bottom: 0, right: -10)
        chatButton.addTarget(self, action: #selector(chatClicked), for: .touchUpInside)
        
    }
    
    @objc func chatClicked() {
        print("Chat clicked")
    }
}

Output

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220

3 Answers3

2

You could create a custom view with label and button and set it as titleView on navigationItem of the HomeNavController.

Check out this answer

EDIT:

Alternatively you can set new label as leftBarButtonItem

How do I left align the title of a navigation bar in Xcode?

Witek Bobrowski
  • 3,749
  • 1
  • 20
  • 34
1

If you want to implement this navigation on another page, you could just create custom view controller instead of create the custom navigation controller.

import UIKit

class CustomViewController: UIViewController {
    
    var tabTitle: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        configure()
    }

    private func configure() {
    
        navigationController?.navigationBar.isHidden = false
        navigationController?.navigationBar.isTranslucent = false

        navigationController?.navigationBar.tintColor = .white
        navigationController?.navigationBar.barTintColor = .primary
    
        let nameLabel = UILabel(frame: .zero)
        nameLabel.textColor = .white
        nameLabel.tintColor = .white
        nameLabel.text = self.tabTitle
        navigationItem.leftBarButtonItem = UIBarButtonItem(customView: nameLabel)

    
        let chatButton = UIButton(type: .system)
        chatButton.setImage(UIImage(named: "home-chat")?.withRenderingMode(.alwaysOriginal), for: .normal)
        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: chatButton)
        chatButton.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: 0, bottom: 0, right: -10)
        chatButton.addTarget(self, action: #selector(chatClicked), for: .touchUpInside)
    
    }

    @objc func chatClicked() {
         print("Chat clicked")
    }
}

Now if you want to change view controller with the same navigation bar, you can use CustomViewController.

class HomeViewController: CustomViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

}

And if you want to change the title you can set the title of view controller before you present or add to rootviewcontroller

let viewController = HomeViewController()
viewController.tabTitle = "Hommme"
let navController = CustomViewController(rootViewController: viewController)
self.present(navController!, animated: true, completion: nil)

If you use storyboard you can change the title of the view controller on the attibure inspector.

Note:

  • You need to adjust the code if you want change the title in the middle of presenting.
  • If this navigation bar only show on 1 page, you just need to change in the view controller directly instead create custom view controller.
  • Thanks for your effort. Your answer seems it going to work, but sadly I'm using a BaseController all over my VC's and I don't want to implement a navigation bar on it. – sala7khaled Dec 28 '20 at 15:26
0

I semi hard-coded it. I have implemented configure() function on my view controller and it works. Sadly, I have to drag this function for every view controller on my tabBar.