UIBarButtonItem
navigation bar
programmatically
iOS development
Swift

UIBarButtonItem in navigation bar programmatically?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

To add a UIBarButtonItem programmatically, you usually create it in a UIViewController and assign it to navigationItem.leftBarButtonItem or navigationItem.rightBarButtonItem. The important requirement is that the view controller must be inside a UINavigationController, otherwise there is no navigation bar to display the item.

Add a basic bar button item

The classic target-action pattern is still the standard approach:

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

If this controller is pushed onto a navigation stack, the Add button appears on the right side of the navigation bar. The @objc action method is required because the selector uses Objective-C runtime messaging under the hood.

Use a text button or image button

You are not limited to system items. You can create a button with a title:

swift
1navigationItem.leftBarButtonItem = UIBarButtonItem(
2    title: "Cancel",
3    style: .plain,
4    target: self,
5    action: #selector(cancelTapped)
6)

Or an SF Symbols image:

swift
1navigationItem.rightBarButtonItem = UIBarButtonItem(
2    image: UIImage(systemName: "square.and.arrow.up"),
3    style: .plain,
4    target: self,
5    action: #selector(shareTapped)
6)

This is often the cleanest choice when the action should match platform conventions such as share, edit, close, or compose.

Add multiple buttons

If you need more than one item on a side, use the array properties:

swift
1navigationItem.rightBarButtonItems = [
2    UIBarButtonItem(
3        image: UIImage(systemName: "square.and.arrow.up"),
4        style: .plain,
5        target: self,
6        action: #selector(shareTapped)
7    ),
8    UIBarButtonItem(
9        barButtonSystemItem: .add,
10        target: self,
11        action: #selector(addTapped)
12    )
13]

The order of the array controls the order in the navigation bar. This is useful for screens that expose a primary action and a secondary utility action side by side.

Use a custom view when standard items are not enough

If the built-in styles are too limited, UIBarButtonItem can host a custom view:

swift
1let button = UIButton(type: .system)
2button.setTitle("Filter", for: .normal)
3button.addTarget(self, action: #selector(filterTapped), for: .touchUpInside)
4
5navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)

This gives you more control over layout and styling, but it also means you take on more responsibility for sizing, accessibility, and platform consistency. Use it when standard bar button items genuinely cannot express what you need.

Make sure the navigation controller exists

A very common source of confusion is correct code that still shows no button. In most cases, the issue is not the UIBarButtonItem itself; it is that the view controller is presented modally without a navigation controller.

For example:

swift
let vc = DetailsViewController()
let nav = UINavigationController(rootViewController: vc)
present(nav, animated: true)

Wrapping the controller in UINavigationController gives it a navigation bar, so the item becomes visible.

Common Pitfalls

The most common mistake is setting navigationItem.rightBarButtonItem on a controller that is not embedded in a navigation controller. The code runs, but nothing appears.

Another common issue is forgetting the @objc action method or using the wrong selector name. In that case, the button may exist but tapping it will fail.

People also overuse customView when a standard item would be better. Standard items integrate more naturally with system appearance, spacing, and accessibility.

Finally, if you configure the item before viewDidLoad or later overwrite navigationItem properties elsewhere, the bar button can disappear unexpectedly.

Summary

  • Create UIBarButtonItem instances and assign them to the view controller's navigationItem.
  • Use system items, titles, or SF Symbols depending on the action you want.
  • Use rightBarButtonItems or leftBarButtonItems for multiple buttons.
  • Wrap the controller in UINavigationController if there is no navigation bar yet.
  • Prefer standard bar button items over custom views unless you need custom behavior or styling.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.