将UIBarButtonItem设为backBarButtonItem时Action不生效,如何解决?
你这是踩了UINavigationItem的一个常见坑,我来给你掰扯清楚:
问题根源
navigationItem.backBarButtonItem根本不是用来设置当前页面返回按钮的!它的真实作用是:当你把当前页面push到导航栈之后,给下一个页面的左上角返回按钮设置样式。而且这个返回按钮的点击逻辑是被UINavigationController接管的——不管你设置了什么target和action,导航控制器都会直接用默认的popViewController逻辑,你的自定义事件自然不会被触发。
而leftBarButtonItem是直接给当前页面的左侧按钮赋值,完全由你控制,所以你的action能正常生效。
解决办法
分两种场景给你方案:
场景1:想自定义当前页面的返回按钮(要自己的点击事件)
直接用leftBarButtonItem,如果需要保留iOS默认的滑动返回手势,记得额外处理:
override func viewDidLoad() { super.viewDidLoad() // 创建自定义返回按钮 let backItem = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(backNavigationClick)) navigationItem.leftBarButtonItem = backItem // 保留滑动返回手势(可选,根据你的需求) navigationController?.interactivePopGestureRecognizer?.delegate = self } @objc func backNavigationClick() { print("back clicked") // 手动执行页面pop,和默认返回按钮逻辑一致 navigationController?.popViewController(animated: true) } // 实现手势代理,确保滑动返回正常工作 extension YourViewController: UIGestureRecognizerDelegate { func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { // 只有导航栈里有多个页面时,才允许滑动返回 return (navigationController?.viewControllers.count ?? 0) > 1 } }
场景2:只想修改下一个页面的返回按钮文字(不需要自定义点击事件)
那你可以继续用backBarButtonItem,但不用设置target和action——反正设置了也没用,导航控制器会用默认逻辑:
override func viewDidLoad() { super.viewDidLoad() // 只设置标题,target和action设为nil即可 let backItem = UIBarButtonItem(title: "Back", style: .plain, target: nil, action: nil) navigationItem.backBarButtonItem = backItem }
一句话总结
backBarButtonItem:管下一页的返回按钮样式,点击逻辑归导航控制器,自定义action无效;leftBarButtonItem:管当前页的左侧按钮,完全自定义逻辑,但要手动处理页面跳转。
内容的提问来源于stack exchange,提问作者Aviran
相关产品推荐
相关产品推荐

