Navigation bar

Controllers within a navigation controller share the same navigation bar. Therefore, you need to set up a navigation bar for each controller.

Navigation bar accessible via the navigationBar property from any controller.

Customize the content of the navigation bar with the navigationItem property of the controller. It has the following useful properties:

  • backBarButtonItem - back button with word "back"
  • leftBarButtonItem - left button, you can use it as back button that has only icon
  • rightBarButtonItem - right button, you can use it as menu button
  • rightBarButtonItems - you can use it as action buttons

UIBarButtonItem represents a button for a toolbar. It usually shows an icon and text. But you can also create a button with your custom view.

class MyController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        setupNavigationBar()
        // ...
    }
    
    private func setupNavigationBar() {  
        // make custom back button
        let backImage = UIImage(named: "ic-back")
        let backButton = UIBarButtonItem(image: backImage,
                                         style: .plain,
                                         target: self,
                                         action: #selector(routeBack))
        // set tint color of icon if you don't want default color
        backButton.tintColor = Theme.appColor1 
        navigationItem.leftBarButtonItem = backButton
        
        // navigationItem.backBarButtonItem = ...
        
        guard let navigationBar = navigationController?.navigationBar 
        else { return }
        
        // setup navigation bar - background and 
        // default tint color for text and icons
        navigationBar.backgroundColor = .white
        navigationBar.tintColor = Theme.appColor2 
        
        // setup large black title
        title = "title text"
        navigationBar.titleTextAttributes = [.foregroundColor:UIColor.black,
                                             .font: UIFont.boldSystemFont(ofSize: 20)]
        navigationBar.prefersLargeTitles = false
    }
    
    @objc
    private func routeBack() {
        navigationController?.popViewController(animated: true)
    }
    
    // ...
}    

Also you can customize navigation bar in storyboard.

Change tint colors
navigationBar.isTranslucent = false
navigationBar.barTintColor = .cyan
navigationBar.tintColor = .brown
Change background image
navigationBar.setBackgroundImage(UIImage(named: "bg_image"), for: .default)
navigationBar.shadowImage = UIImage(named: "bg_image_shadow")
Clear background
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = true
view.backgroundColor = UIColor.clear
Remove border
navigationBar.setBackgroundImage(UIImage(), for:.default)
navigationBar.shadowImage = UIImage()
navigationBar.layoutIfNeeded()
Customize the back button
// remove title
navigationItem.backBarButtonItem 
    = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
// set light blue color
navigationItem.backBarButtonItem?.tintColor = UIColor.cgLightBlue
Add right button
navigationItem.rightBarButtonItem = 
                       UIBarButtonItem(title: "Add",
                                       style: .plain, 
                                       target: self,     
                                       action: #selector(onClickRight))

// ...

@objc 
func onClickRight() {
  // ... do something
}
Add multiple right buttons
let add = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: #selector(onClickAdd))
let playButton = UIButton(type: .custom)playButton.setImage(UIImage(named: "plus"), for: .normal)
playButton.addTarget(self, action: #selector(onClickPlay), for: .touchUpInside)
playButton.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
let barButton = UIBarButtonItem(customView: playButton)
navigationItem.rightBarButtonItems = [add, barButton]

// ...

@objc 
func onClickAdd() {
  // ... do something
}

@objc 
func onClickPlay() {
  // ... do something
}
Customize bar button
let playButton = UIButton(type: .custom)
playButton.setImage(UIImage(named: "plus"), for: .normal)
playButton.addTarget(self, action: #selector(playTapped), for: .touchUpInside)
playButton.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
let barButton = UIBarButtonItem(customView: playButton)