swift
iOS
UIBarButtonItem
coding
programming

Make a UIBarButtonItem disappear using swift IOS

Master System Design with Codemia

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

Introduction

Hiding a UIBarButtonItem in iOS is usually done by removing it from the navigation item rather than trying to toggle a hidden property. The safest approach depends on whether the button should disappear temporarily or permanently for a screen state. A clear show and hide pattern keeps navigation behavior predictable.

Remove and Restore Bar Button Items

UIBarButtonItem itself does not provide a direct visibility toggle. Instead, set the corresponding navigation item property to nil, then restore the saved button when needed.

swift
1import UIKit
2
3final class ProfileViewController: UIViewController {
4    private var savedEditButton: UIBarButtonItem?
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8
9        let edit = UIBarButtonItem(
10            barButtonSystemItem: .edit,
11            target: self,
12            action: #selector(onEdit)
13        )
14        navigationItem.rightBarButtonItem = edit
15        savedEditButton = edit
16    }
17
18    func setEditVisible(_ visible: Bool) {
19        navigationItem.rightBarButtonItem = visible ? savedEditButton : nil
20    }
21
22    @objc private func onEdit() {
23        print("Edit tapped")
24    }
25}

This pattern is simple and works well for permission-based UI changes.

Hide During Async Operations

A common requirement is to disable edit actions while a network request is active. You can remove the button before the request and restore it when done.

swift
1import UIKit
2
3extension ProfileViewController {
4    func refreshProfile() {
5        setEditVisible(false)
6
7        Task {
8            do {
9                try await Task.sleep(nanoseconds: 1_000_000_000)
10                // Simulated network refresh.
11            } catch {
12                print("refresh failed: \(error)")
13            }
14
15            await MainActor.run {
16                self.setEditVisible(true)
17            }
18        }
19    }
20}

Always switch back to the main actor before touching UIKit.

Decide Between Hide and Disable

Sometimes disabling is better than removing. If the action should remain discoverable, keep the button and set isEnabled to false. If the action should be unavailable or misleading in a given state, removing it is cleaner for users.

swift
navigationItem.rightBarButtonItem?.isEnabled = false

Use a consistent rule across your app so navigation controls behave the same way on each screen.

Coordinate Visibility with App State

Bar button visibility should be driven by state, not scattered view-controller side effects. A common pattern is to compute visibility from permission state and loading state, then apply it in one method. This avoids inconsistent navigation behavior after repeated screen transitions.

swift
1import UIKit
2
3final class DocumentViewController: UIViewController {
4    private var canEdit = false
5    private var isLoading = false
6    private var editButton: UIBarButtonItem!
7
8    override func viewDidLoad() {
9        super.viewDidLoad()
10        editButton = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(onEdit))
11        navigationItem.rightBarButtonItem = editButton
12        refreshBarButtons()
13    }
14
15    private func refreshBarButtons() {
16        let shouldShow = canEdit && !isLoading
17        navigationItem.rightBarButtonItem = shouldShow ? editButton : nil
18    }
19
20    func updatePermission(_ value: Bool) {
21        canEdit = value
22        refreshBarButtons()
23    }
24
25    func setLoading(_ value: Bool) {
26        isLoading = value
27        refreshBarButtons()
28    }
29
30    @objc private func onEdit() {
31        print("edit action")
32    }
33}

This approach keeps UI decisions deterministic and easy to test. It also prevents cases where one code path removes a button and another path forgets to restore it. In larger apps, state-driven UI updates are far more reliable than one-off imperative updates.

Test Navigation Behavior Across Transitions

After implementing show and hide logic, verify behavior when pushing and popping view controllers. Navigation bars can be reconfigured during transitions, and hidden items may reappear if setup code runs in multiple lifecycle methods.

A practical test plan includes initial load, permission changes, pull-to-refresh flow, and returning from a child screen. Running these checks prevents inconsistent controls in production navigation stacks.

Document the chosen hide-versus-disable rule so all contributors implement the same navigation behavior.

Consistency improves usability across the app.

Common Pitfalls

  • Trying to call a hidden property on UIBarButtonItem, which does not exist.
  • Modifying navigation items from a background thread.
  • Recreating buttons repeatedly and losing target-action wiring.
  • Removing a button without preserving a reference for restoration.

Summary

  • Hide bar button items by assigning nil to navigation item slots.
  • Restore from a saved reference when state changes.
  • Use disabling when you want visibility without interaction.
  • Keep all UIKit changes on the main thread.

Course illustration
Course illustration

All Rights Reserved.