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

Swift返回根控制器后UIBarButtonItem仍高亮的问题求助

UIBarButtonItem 右滑返回根控制器后异常高亮的问题

问题现象:所有UIBarButtonItem均配置了跳转视图控制器的target-action逻辑,但偶尔通过右滑手势返回根控制器后,根控制器的UIBarButtonItem会持续保持高亮状态,该问题并非必现。

正常状态截图:导航栏正常状态
异常状态截图:按钮高亮异常状态


可能原因

  1. 右滑返回属于UINavigationController的交互式转场手势,在手势执行过程中,系统可能未同步触发按钮高亮状态的重置逻辑,导致状态残留。
  2. 按钮触发跳转时会进入高亮状态,若交互式转场的中途回调未正确将按钮的highlighted属性置为false,就会出现该异常。

解决方法

方法1:根控制器显示时强制重置按钮状态

在根控制器的viewDidAppear方法中,遍历导航栏所有按钮并手动关闭高亮状态:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    // 重置左侧所有按钮
    navigationItem.leftBarButtonItems?.forEach { $0.isHighlighted = false }
    // 重置右侧所有按钮
    navigationItem.rightBarButtonItems?.forEach { $0.isHighlighted = false }
}

方法2:自定义UIBarButtonItem管理高亮状态

自定义BarButtonItem子类,在事件触发时主动控制高亮状态,避免残留:

class CustomBarButtonItem: UIBarButtonItem {
    override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
        // 先取消高亮再执行跳转逻辑
        isHighlighted = false
        super.sendAction(action, to: target, for: event)
    }
    
    // 针对自定义View的按钮,额外监听触摸事件重置状态
    override var customView: UIView? {
        didSet {
            guard let button = customView as? UIButton else { return }
            button.addTarget(self, action: #selector(resetHighlight), for: [.touchUpInside, .touchCancel])
        }
    }
    
    @objc private func resetHighlight() {
        isHighlighted = false
    }
}

方法3:监听导航控制器转场通知重置状态

通过监听导航控制器的页面显示通知,在每次页面切换完成后重置按钮状态:

class RootViewController: UIViewController {
    private var navShowObserver: NSObjectProtocol?

    override func viewDidLoad() {
        super.viewDidLoad()
        guard let nav = navigationController else { return }
        
        navShowObserver = NotificationCenter.default.addObserver(
            forName: UINavigationController.didShowViewControllerNotification,
            object: nav,
            queue: .main
        ) { [weak self] _ in
            self?.resetBarButtonsHighlight()
        }
    }

    deinit {
        if let observer = navShowObserver {
            NotificationCenter.default.removeObserver(observer)
        }
    }

    private func resetBarButtonsHighlight() {
        navigationItem.leftBarButtonItems?.forEach { $0.isHighlighted = false }
        navigationItem.rightBarButtonItems?.forEach { $0.isHighlighted = false }
    }
}

额外排查点

  • 检查自定义导航栏子类是否在转场过程中手动修改过按钮高亮状态;
  • 确认按钮的adjustsImageWhenHighlighted属性是否被错误配置;
  • 若使用第三方导航框架,排查框架是否存在转场状态同步的bug。

内容的提问来源于stack exchange,提问作者Eloi Canals Pascual

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:40:22