You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

切换ViewController时如何动态添加/隐藏UIBarButtonItem?

Solution: Dynamically Add/Remove UIBarButtonItem for Specific ViewController

Absolutely feasible! This is a super common scenario for customizing navigation bars in iOS, and there are a couple of clean, reliable ways to implement this—whether you want to handle it directly in your target ViewController or via the navigation controller's delegate.

Option 1: Use ViewController Lifecycle Methods

This is the most straightforward approach if you only need this behavior for a single ViewController. We'll leverage viewWillAppear (to add the button when the screen is about to show) and viewWillDisappear (to remove it when leaving the screen).

Step 1: Declare a Property for the Dynamic Button

First, add a stored property to your ViewController to keep track of the button we'll create dynamically (this prevents us from re-creating it every time the screen appears):

private var filterBtn: UIBarButtonItem?

Step 2: Add the Button When the View Appears

In viewWillAppear, we'll grab the existing bar button items from Storyboard, append our new button, and update the navigation item:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    // Create the button only once
    if filterBtn == nil {
        filterBtn = UIBarButtonItem(title: "Filter", style: .plain, target: self, action: #selector(filterAction(sender:)))
    }
    
    // Get existing buttons (fallback to empty array if none exist)
    var existingButtons = navigationItem.rightBarButtonItems ?? []
    // Add our dynamic button to the array
    existingButtons.append(filterBtn!)
    // Assign back to update the navigation bar
    navigationItem.rightBarButtonItems = existingButtons
}

Step 3: Remove the Button When the View Disappears

In viewWillDisappear, we'll filter out our dynamic button from the existing array:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    
    // Remove only our dynamic button, keep the Storyboard ones intact
    navigationItem.rightBarButtonItems = navigationItem.rightBarButtonItems?.filter { $0 !== filterBtn }
}

Step 4: Add the Button Action

Don't forget to implement the selector for your button's tap event:

@objc private func filterAction(sender: UIBarButtonItem) {
    // Add your button logic here
    print("Filter button tapped!")
}

Option 2: Use UINavigationController Delegate

If you need this behavior across multiple ViewControllers or want a more centralized approach, use the navigation controller's delegate methods.

Step 1: Set Up the Delegate

In your ViewController's viewDidLoad, set itself as the navigation controller's delegate:

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.delegate = self
}

Step 2: Implement the Delegate Method

Add an extension to conform to UINavigationControllerDelegate and handle the navigation transition:

extension YourViewController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController === self {
            // Add the dynamic button (same creation logic as Option 1)
            if filterBtn == nil {
                filterBtn = UIBarButtonItem(title: "Filter", style: .plain, target: self, action: #selector(filterAction(sender:)))
            }
            var existingButtons = navigationItem.rightBarButtonItems ?? []
            existingButtons.append(filterBtn!)
            navigationItem.rightBarButtonItems = existingButtons
        } else {
            // Remove the dynamic button when navigating away
            navigationItem.rightBarButtonItems = navigationItem.rightBarButtonItems?.filter { $0 !== filterBtn }
        }
    }
}

Key Notes

  • Avoid Duplicate Buttons: By storing the button as a property and only creating it once, we prevent adding multiple instances of the filter button every time the ViewController appears.
  • Preserve Storyboard Buttons: Using rightBarButtonItems (the array version) instead of rightBarButtonItem ensures we keep the two buttons you added in Storyboard while adding the third dynamically.
  • TabBar Compatibility: Both methods work seamlessly if your ViewController is part of a UITabBarController, since viewWillAppear and the navigation delegate methods will still trigger when switching tabs.

内容的提问来源于stack exchange,提问作者user11733397

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:40:09