运行时修改UIButton点击事件后,Push视图控制器出现重复跳转求助
问题原因与修复方案
这个问题我之前也碰到过!核心原因很简单:你每次选中Cell时都给按钮新增了一个点击事件绑定,但从来没有移除之前绑定的旧事件。时间一长,按钮的响应队列里就积累了多个action,点击时自然会依次触发所有添加过的跳转逻辑。
方案一:添加新事件前先清除旧绑定
最直接的修复方式,就是在每次调用addTarget之前,先移除按钮上所有针对.touchUpInside事件的绑定。这样就能保证按钮永远只有一个活跃的点击事件。
修改你的didSelectRowAt方法如下:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // 先清除所有已有的点击事件绑定 self.botButton.removeTarget(nil, action: nil, for: .touchUpInside) if indexPath.row == 0{ self.botButton.addTarget(self, action: #selector(self.showA), for: .touchUpInside) } else{ self.botButton.addTarget(self, action: #selector(self.showB), for: .touchUpInside) } }
方案二:统一按钮点击逻辑(更推荐)
其实我们完全可以不用动态切换按钮的target,而是通过记录当前选中的Cell位置,在按钮的统一点击方法里做判断。这种方式代码更简洁,也从根源上避免了重复绑定的问题。
步骤如下:
- 先定义一个变量记录当前选中的行:
var selectedRow = 0 // 默认选中第0行,和你的初始逻辑匹配
- 在
didSelectRowAt里只更新这个变量:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { selectedRow = indexPath.row // 可选:如果需要高亮选中的Cell,可以在这里处理选中状态 tableView.deselectRow(at: indexPath, animated: true) }
- 给按钮绑定一个统一的点击方法,在方法里根据
selectedRow判断跳转:
// 先给botButton绑定这个方法(可以在viewDidLoad里一次性绑定,不用动态修改) override func viewDidLoad() { super.viewDidLoad() self.botButton.addTarget(self, action: #selector(handleButtonTap), for: .touchUpInside) } @objc func handleButtonTap(){ if selectedRow == 0 { let showParcelsViewController = self.storyboard?.instantiateViewController(withIdentifier: "showA") as! showAVC self.navigationController?.pushViewController(showParcelsViewController, animated: true) } else { let decribeland = self.storyboard?.instantiateViewController(withIdentifier: "showB") as! showBVC self.navigationController?.pushViewController(decribeland, animated: true) } }
这种方式不仅解决了重复跳转的问题,代码结构也更清晰,后期维护起来更方便。
内容的提问来源于stack exchange,提问作者Omer Tekbiyik
相关产品推荐
相关产品推荐

