iOS
Swift
UINavigationBar
CustomBackButton
iOSDevelopment

UINavigationBar custom back button without title

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

In UIKit, the back button title is derived from the previous view controller's navigation item. If you want the standard back behavior but no visible title, the cleanest solution is to configure the previous screen rather than replacing the button on the current screen.

Why the Back Title Comes from the Previous Screen

This detail trips people up: the back button shown on DetailViewController is controlled by ListViewController, because the navigation bar uses the previous item's backBarButtonItem or back button display settings.

If you set properties on the current view controller after it has been pushed, the default back item may already be derived from the previous controller's title. That is why many "custom back button" attempts accidentally break the swipe-to-go-back gesture or require manual pop logic.

Preferred Solution on Modern iOS

On iOS 14 and later, Apple added backButtonDisplayMode, which is the simplest way to hide the title while keeping the standard arrow and navigation behavior.

Set it on the previous screen:

swift
1import UIKit
2
3final class ListViewController: UIViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6        title = "Products"
7        navigationItem.backButtonDisplayMode = .minimal
8    }
9}

When ListViewController pushes another screen, the next screen shows the back indicator without the text label. This keeps the system appearance, accessibility behavior, and interactive pop gesture intact.

Custom Back Indicator Image Without a Title

If you want a branded arrow, configure the navigation bar appearance rather than creating a plain left bar button item. This keeps the default navigation behavior while changing the visual asset.

swift
1import UIKit
2
3final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
4    var window: UIWindow?
5
6    func scene(
7        _ scene: UIScene,
8        willConnectTo session: UISceneSession,
9        options connectionOptions: UIScene.ConnectionOptions
10    ) {
11        let appearance = UINavigationBarAppearance()
12        appearance.configureWithOpaqueBackground()
13        appearance.backgroundColor = .systemBackground
14
15        let image = UIImage(systemName: "chevron.backward")
16        appearance.setBackIndicatorImage(image, transitionMaskImage: image)
17
18        let navBar = UINavigationBar.appearance()
19        navBar.standardAppearance = appearance
20        navBar.scrollEdgeAppearance = appearance
21        navBar.compactAppearance = appearance
22
23        window?.makeKeyAndVisible()
24    }
25}

Combine this with .minimal on the previous controller and you get a custom icon with no title.

Older UIKit Approach

If you support earlier iOS versions, set an empty-titled UIBarButtonItem on the previous controller:

swift
1import UIKit
2
3final class ListViewController: UIViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6        title = "Products"
7        navigationItem.backBarButtonItem = UIBarButtonItem(
8            title: "",
9            style: .plain,
10            target: nil,
11            action: nil
12        )
13    }
14}

This changes the text displayed when the next controller is shown, while the navigation controller still manages the pop action.

You can push the detail screen normally:

swift
let detail = DetailViewController()
navigationController?.pushViewController(detail, animated: true)

No custom selector is necessary unless you truly want a nonstandard navigation flow.

When to Use a Fully Custom Button

There are cases where you want a left bar button item with custom layout, analytics, or multiple actions. In that case, create one intentionally and wire the pop behavior yourself:

swift
1import UIKit
2
3final class DetailViewController: UIViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6
7        let button = UIButton(type: .system)
8        button.setImage(UIImage(systemName: "arrow.backward"), for: .normal)
9        button.setTitle("", for: .normal)
10        button.addTarget(self, action: #selector(goBack), for: .touchUpInside)
11
12        navigationItem.leftBarButtonItem = UIBarButtonItem(customView: button)
13    }
14
15    @objc private func goBack() {
16        navigationController?.popViewController(animated: true)
17    }
18}

This works, but it is more code and you lose some of the built-in behavior unless you reproduce it carefully.

Common Pitfalls

The most common mistake is setting backBarButtonItem on the destination controller. The back button belongs to the previous navigation item, so that code appears to do nothing.

Another pitfall is replacing the default back button when only the title needs to disappear. A custom left item can disable the interactive swipe-back gesture and create inconsistent accessibility behavior.

Developers also forget that appearance APIs and per-screen navigation item settings solve different problems. Use appearance for the global icon and tint, and use the previous controller's navigation item for the title behavior.

Finally, test on the iOS versions you support. backButtonDisplayMode is excellent, but it is not the universal fallback for older deployments.

Summary

  • The back button shown on a screen is configured by the previous view controller.
  • On iOS 14 and later, navigationItem.backButtonDisplayMode = .minimal is the cleanest way to hide the title.
  • Use UINavigationBarAppearance to provide a custom back indicator image while keeping system behavior.
  • For older iOS versions, set an empty backBarButtonItem on the previous controller.
  • Only create a fully custom left button when you really need nonstandard behavior.

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.