iOS development
UIBarButtonItem
navigation bar
Swift
UIKit

How to add multiple UIBarButtonItems on right side of Navigation Bar?

Master System Design with Codemia

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

Introduction

UIKit supports multiple buttons on the right side of a navigation bar through navigationItem.rightBarButtonItems. The basic API is simple, but good production code also needs a clear policy for button order, action wiring, dynamic state updates, and accessibility.

Use rightBarButtonItems for Multiple Actions

If you need more than one action, create the individual UIBarButtonItem instances and assign them as an array.

swift
1import UIKit
2
3final class InboxViewController: UIViewController {
4    private lazy var searchButton = UIBarButtonItem(
5        barButtonSystemItem: .search,
6        target: self,
7        action: #selector(didTapSearch)
8    )
9
10    private lazy var addButton = UIBarButtonItem(
11        barButtonSystemItem: .add,
12        target: self,
13        action: #selector(didTapAdd)
14    )
15
16    override func viewDidLoad() {
17        super.viewDidLoad()
18        navigationItem.rightBarButtonItems = [addButton, searchButton]
19    }
20
21    @objc private func didTapSearch() {
22        print("search tapped")
23    }
24
25    @objc private func didTapAdd() {
26        print("add tapped")
27    }
28}

That is the standard pattern. You do not add them one by one with repeated assignments to rightBarButtonItem, because that property only holds a single item.

Be Intentional About Ordering

When multiple items are shown, source order matters. The exact visual placement can feel counterintuitive at first, so the safest approach is to pick an ordering convention for your project and test it on a running screen instead of relying on memory.

A useful team rule is:

  • primary action closest to the edge
  • secondary action closer to the title

Then apply that rule consistently across screens. Consistency matters more than any one preferred order because users build muscle memory from repetition.

If you support right-to-left languages, verify the result in a localized simulator. Navigation bars adapt to layout direction, and assumptions based only on left-to-right development can be wrong.

Prefer System Items Before Custom Views

System bar button items are usually the best starting point because they inherit platform behavior, spacing, tinting, and accessibility patterns automatically.

Use a custom view only when you need something the standard item cannot express, such as a badge, a custom animated control, or a compound button.

swift
1let bellButton = UIButton(type: .system)
2bellButton.setImage(UIImage(systemName: "bell"), for: .normal)
3bellButton.addTarget(self, action: #selector(didTapNotifications), for: .touchUpInside)
4
5let bellItem = UIBarButtonItem(customView: bellButton)
6navigationItem.rightBarButtonItems = [bellItem, addButton]

Custom views are more work. You are responsible for touch target size, layout behavior, accessibility labels, and any state styling that system items would otherwise handle for you.

Centralize Updates Instead of Scattering State Changes

Navigation bar buttons often need to enable, disable, hide, or swap based on screen state. Keep that logic in one place.

swift
1private func updateBarButtons(canCreate: Bool, isLoading: Bool) {
2    addButton.isEnabled = canCreate && !isLoading
3    searchButton.isEnabled = !isLoading
4}

Call that method from lifecycle or state-update code instead of toggling button state in multiple unrelated callbacks. Centralized updates reduce drift and make debugging much easier.

If the set of actions changes entirely, rebuild the array explicitly:

swift
1private func applyEditingMode(_ isEditingList: Bool) {
2    if isEditingList {
3        navigationItem.rightBarButtonItems = [UIBarButtonItem(systemItem: .done)]
4    } else {
5        navigationItem.rightBarButtonItems = [addButton, searchButton]
6    }
7}

Do Not Skip Accessibility

Icon-only buttons need meaningful accessibility labels and, when useful, hints.

swift
1searchButton.accessibilityLabel = "Search messages"
2searchButton.accessibilityHint = "Opens the search screen"
3
4addButton.accessibilityLabel = "Create message"
5addButton.accessibilityHint = "Starts a new draft"

That matters even more for custom-view bar buttons, where accessibility support is no longer automatic in the same way it is for standard system items.

Common Pitfalls

The most common mistake is using rightBarButtonItem repeatedly and expecting multiple buttons to remain visible. Each assignment replaces the previous item.

Another common issue is relying on spacing hacks instead of letting the system handle default layout. Developers also often recreate bar buttons inside multiple lifecycle methods and then wonder why order or state becomes inconsistent. Finally, icon-only controls without accessibility labels are a usability regression even when they look correct visually.

Summary

  • Use navigationItem.rightBarButtonItems when you need multiple right-side actions.
  • Create items explicitly and assign them as an array in a deliberate order.
  • Prefer system bar button items unless you truly need a custom view.
  • Centralize enable, disable, and replacement logic in one update method.
  • Add accessibility labels and test ordering on real devices and localized layouts.

Course illustration
Course illustration

All Rights Reserved.