Swift返回根控制器后UIBarButtonItem仍高亮的问题求助
问题现象:所有UIBarButtonItem均配置了跳转视图控制器的target-action逻辑,但偶尔通过右滑手势返回根控制器后,根控制器的UIBarButtonItem会持续保持高亮状态,该问题并非必现。
正常状态截图:
异常状态截图:
可能原因
- 右滑返回属于UINavigationController的交互式转场手势,在手势执行过程中,系统可能未同步触发按钮高亮状态的重置逻辑,导致状态残留。
- 按钮触发跳转时会进入高亮状态,若交互式转场的中途回调未正确将按钮的
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
相关产品推荐
相关产品推荐

