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

iOS开发:如何为UITableView行设置两个Segue?prepare调用异常问题

解决TableView行点击与滑动触发不同Segue的问题

核心问题分析

你遇到的并非prepare(for:sender:)未调用,而是滑动操作不会选中行,导致代码里guard let indexPath = tableView.indexPathForSelectedRow else {return}直接退出方法,看起来像是没触发。另外,同一行无法直接拖出两个Segue,正确做法是从TableViewController本身创建Segue。

解决方案步骤

1. 正确创建Segue

在Storyboard中,从你的TableViewController(而非TableViewCell)分别拖线到AddWordsViewController和QuizViewController,分别设置Segue标识符为editQuiz和showQuiz。

2. 修改滑动操作中的performSegue调用

把滑动操作里的sender参数改为当前行的indexPath,确保prepare方法能直接拿到目标行位置:

override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let editAction = UIContextualAction(style: .normal, title: "Add"){(_,_, completionHandler) in
        // 传递indexPath作为sender
        self.performSegue(withIdentifier: "editQuiz", sender: indexPath)
        tableView.reloadData()
        completionHandler(true) // 务必调用完成回调
    }
    let deleteAction = UIContextualAction(style: .destructive, title: "Delete"){(_,_, completionHandler) in
        CoreDataManager.shared.deleteSomeQuizData(data: CoreDataManager.shared.quizzes[indexPath.row], indexNumber: indexPath.row)
        self.navigationItem.title = "\(CoreDataManager.shared.quizzes.count) quizzes"
        tableView.reloadData()
        completionHandler(true)
    }
    return UISwipeActionsConfiguration(actions: [deleteAction, editAction])
}

3. 修改行点击事件的performSegue调用

同样传递indexPath作为sender,并可选取消行选中状态:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    self.performSegue(withIdentifier: "showQuiz", sender: indexPath)
    tableView.deselectRow(at: indexPath, animated: true)
}

4. 重构prepare方法的逻辑

不再依赖选中行,而是从sender获取indexPath,兼容两种触发场景:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // 优先从sender取indexPath,无则 fallback 到选中行
    guard let indexPath = sender as? IndexPath ?? tableView.indexPathForSelectedRow else {
        return
    }
    
    if segue.identifier == "editQuiz" {
        guard let destination = segue.destination as? AddWordsViewController else {
            return
        }
        // 按需传递数据,比如当前行的Quiz数据
        // destination.targetQuiz = CoreDataManager.shared.quizzes[indexPath.row]
    }
    
    if segue.identifier == "showQuiz" {
        guard let destination = segue.destination as? QuizViewController else {
            return
        }
        let targetQuiz = CoreDataManager.shared.quizzes[indexPath.row]
        destination.from = Int(targetQuiz.from)
        destination.to = Int(targetQuiz.to)
    }
}

关键说明

  • 滑动操作不会触发行选中状态,因此原来依赖tableView.indexPathForSelectedRow的逻辑会失效,传递indexPath作为sender是更可靠的方式。
  • 从ViewController本身创建Segue,就能通过performSegue(withIdentifier:sender:)灵活触发不同跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:05:52