iOS
Navigation Controller
Back Button
App Development
Swift Programming

Setting action for back button in navigation controller

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

In a UINavigationController, the default back button automatically pops the current view controller. That is convenient, but it also means there is no simple "set custom callback on the built-in back button" API. If you need custom behavior, the usual solution is to replace the default back button or detect that the controller is being popped.

Understand the Default Behavior First

When controller B is pushed from controller A, the back button shown on B is generated from navigation state. It is not just a normal button that you own directly.

That is why this requirement usually falls into one of two categories:

  • run custom code before navigating back
  • detect that a back navigation already happened

Those two cases should be handled differently.

Option 1: Replace the Back Button

If you want full control over the action, hide the default back button and add your own left bar button item:

swift
1import UIKit
2
3final class EditViewController: UIViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6
7        navigationItem.hidesBackButton = true
8        navigationItem.leftBarButtonItem = UIBarButtonItem(
9            title: "Back",
10            style: .plain,
11            target: self,
12            action: #selector(didTapBack)
13        )
14    }
15
16    @objc private func didTapBack() {
17        print("Run custom logic here")
18        navigationController?.popViewController(animated: true)
19    }
20}

This is the right approach if you need to save draft changes, confirm navigation, or log an analytics event before popping.

Option 2: Detect a Pop in Lifecycle Code

If you only want to know that the user went back, but you do not need to block it, check whether the controller is being removed from its parent:

swift
1override func viewWillDisappear(_ animated: Bool) {
2    super.viewWillDisappear(animated)
3
4    if isMovingFromParent {
5        print("The controller is being popped")
6    }
7}

This is useful for cleanup, lightweight analytics, or releasing temporary resources.

It is not a replacement for a confirmation dialog because by the time this runs, the navigation is already in progress.

Handling Unsaved Changes

Unsaved changes are the most common reason people want a custom back action. In that case, replace the button and show an alert:

swift
1@objc private func didTapBack() {
2    let alert = UIAlertController(
3        title: "Discard changes?",
4        message: "Your edits have not been saved.",
5        preferredStyle: .alert
6    )
7
8    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
9    alert.addAction(UIAlertAction(title: "Discard", style: .destructive) { _ in
10        self.navigationController?.popViewController(animated: true)
11    })
12
13    present(alert, animated: true)
14}

That pattern is more reliable than trying to intercept the internal back button after the fact.

Gesture Navigation Matters Too

When you replace the default back button, be aware of the interactive swipe-back gesture. Depending on configuration, a custom left button may affect the standard navigation experience. Test both tapping and edge-swipe navigation so the screen does not behave inconsistently.

If your screen must block leaving because of unsaved work, handle the gesture case as part of the overall navigation policy rather than assuming only button taps matter.

When You Only Want to Change the Back Title

Sometimes the real need is not a custom action but a custom title. That is set on the previous controller, not the current one:

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    navigationItem.backButtonTitle = "Items"
4}

That preserves native back behavior while changing the label.

Common Pitfalls

The biggest mistake is trying to attach a target-action handler directly to the default back button. The navigation controller manages it; you do not.

Another mistake is using viewWillDisappear to show a confirmation dialog. That is too late for true interception and can produce awkward navigation behavior.

A third issue is replacing the back button without retesting swipe gestures or accessibility behavior.

Summary

  • The built-in navigation back button is managed by UINavigationController, not by your view controller directly.
  • To run custom logic before going back, hide the default back button and add a custom left bar button item.
  • To detect that a pop happened, check isMovingFromParent in viewWillDisappear.
  • Use a confirmation alert for unsaved changes instead of trying to hijack the default button.
  • If you only need a different label, change the back button title rather than replacing the whole 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.