iOS Development
UINavigationController
Swift Programming
iOS Design
Mobile App Development

How to add a right button to a UINavigationController?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In iOS, right navigation bar buttons are attached to a view controller’s navigationItem, not directly to the UINavigationController. This distinction is important when button actions seem not to appear or stop responding. Once configured correctly, right bar buttons are reliable entry points for common actions such as add, save, and filter.

Core Sections

Basic Right Button in a View Controller

In UIKit, set rightBarButtonItem in viewDidLoad:

swift
1import UIKit
2
3final class TasksViewController: UIViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6        title = "Tasks"
7
8        navigationItem.rightBarButtonItem = UIBarButtonItem(
9            barButtonSystemItem: .add,
10            target: self,
11            action: #selector(addTapped)
12        )
13    }
14
15    @objc private func addTapped() {
16        print("Add tapped")
17    }
18}

This works when the controller is inside a navigation stack.

Push Controller Into Navigation Stack

If no navigation bar appears, ensure the controller is embedded in UINavigationController:

swift
1let root = TasksViewController()
2let nav = UINavigationController(rootViewController: root)
3window?.rootViewController = nav
4window?.makeKeyAndVisible()

Without this, navigationItem exists but the bar is not visible on screen.

Custom Text and Icon Buttons

You can create custom-labeled buttons:

swift
1navigationItem.rightBarButtonItem = UIBarButtonItem(
2    title: "Save",
3    style: .done,
4    target: self,
5    action: #selector(saveTapped)
6)

Or icon button with SF Symbols:

swift
1let image = UIImage(systemName: "line.3.horizontal.decrease.circle")
2navigationItem.rightBarButtonItem = UIBarButtonItem(
3    image: image,
4    style: .plain,
5    target: self,
6    action: #selector(filterTapped)
7)

Use symbols that match app design language and accessibility expectations.

Multiple Right Buttons

For more than one action, use rightBarButtonItems:

swift
1let filter = UIBarButtonItem(
2    image: UIImage(systemName: "line.3.horizontal.decrease.circle"),
3    style: .plain,
4    target: self,
5    action: #selector(filterTapped)
6)
7
8let add = UIBarButtonItem(
9    barButtonSystemItem: .add,
10    target: self,
11    action: #selector(addTapped)
12)
13
14navigationItem.rightBarButtonItems = [add, filter]

Order in array controls visual placement.

Enable, Disable, and Update State

Buttons should reflect current screen state.

swift
private func refreshSaveAvailability(hasChanges: Bool) {
    navigationItem.rightBarButtonItem?.isEnabled = hasChanges
}

Updating button state prevents invalid actions and improves UX clarity.

Closure-Based UIAction for Modern iOS

On newer iOS versions, you can use UIAction for concise setup:

swift
1if #available(iOS 14.0, *) {
2    navigationItem.rightBarButtonItem = UIBarButtonItem(
3        title: "Done",
4        primaryAction: UIAction { _ in
5            print("Done tapped")
6        }
7    )
8}

This removes selector boilerplate in simple cases.

Storyboard and Interface Builder Option

If using storyboard, you can add a bar button item to navigation item visually and connect an IBAction. Code and storyboard approaches can coexist, but avoid setting conflicting buttons in both places unless intentional.

Common Action Patterns

Right buttons often trigger:

  1. presenting modal screens
  2. pushing detail creation view
  3. committing form data
  4. toggling list filters

Keep action names specific and side effects predictable.

Accessibility and Localization

Set accessibility labels for icon-only buttons:

swift
navigationItem.rightBarButtonItem?.accessibilityLabel = "Filter tasks"

For text buttons, use localized strings rather than hardcoded English so UI remains accessible to all target locales.

Debugging Non-Working Buttons

If button is visible but tap does nothing:

  • verify selector method has @objc
  • verify method signature has no unexpected parameters
  • verify target is alive and not deallocated
  • check gesture recognizers are not intercepting touches

Most failures are selector wiring mistakes.

Common Pitfalls

  • Setting the button on UINavigationController instead of the active view controller navigationItem.
  • Forgetting to embed screen in navigation controller and expecting bar items to appear.
  • Using selector without @objc, causing runtime action lookup failure.
  • Defining both storyboard and code buttons unintentionally and overriding expected UI.
  • Ignoring accessibility labels for icon-only bar buttons.

Summary

  • Add right bar buttons through the current view controller navigationItem.
  • Ensure the controller is inside a UINavigationController stack.
  • Use system items, custom titles, or SF Symbols based on action clarity.
  • Keep button state synchronized with screen state and data validity.
  • Validate selector wiring and accessibility for production-ready behavior.

Course illustration
Course illustration

All Rights Reserved.