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

如何通过Segue从UITableViewController传递数组到ViewController

问题原因

你的代码传值失败核心是执行顺序问题:你在didSelectRowAt方法中先调用了tableView.deselectRow(at: indexPath, animated: true),这行代码会在跳转触发前就清除行的选中状态,等执行到prepare(for:sender:)方法时,self.tableView.indexPathForSelectedRow读取到的是nil,不会进入传值逻辑分支,目标控制器自然拿不到数组数据。
另外存在一个潜在兼容问题:如果你的Segue终点是被UINavigationController包裹的ViewController,直接把segue.destination强转成ViewController会失败,也会导致传值失效。

修复方案

推荐用稳定性最高的方案1,不需要依赖Cell选中态:

  • 方案1:通过sender直接传递选中的IndexPath
    修改MyTableViewController的选中和传值逻辑:

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        // 直接把当前选中的indexPath作为sender传入
        performSegue(withIdentifier: "showDetail", sender: indexPath)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard segue.identifier == "showDetail",
              // 从sender中直接取出indexPath,不再依赖tableView的选中状态
              let indexPath = sender as? IndexPath else {
            return
        }
        // 兼容两种Segue情况:直接连到ViewController、连到包裹ViewController的导航控制器
        let targetVC: ViewController?
        if let nav = segue.destination as? UINavigationController {
            targetVC = nav.topViewController as? ViewController
        } else {
            targetVC = segue.destination as? ViewController
        }
        // 传值
        targetVC?.getDescriptions = faculties[indexPath.row].descriptions
    }
    

    改完之后目标页面的viewDidLoad中print(getDescriptions)就能正常打印出对应的数据,tableView也会自动加载对应行数的内容。

  • 方案2:调整代码执行顺序(改动最小,稳定性稍弱)
    如果不想修改传参逻辑,只需要把取消选中的代码挪到performSegue调用之后即可,保证执行prepare方法时行还处于选中状态:

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = tableView.cellForRow(at: indexPath)
        // 先触发跳转传值
        performSegue(withIdentifier: "showDetail", sender: cell)
        // 传值完成后再取消选中
        tableView.deselectRow(at: indexPath, animated: true)
    }
    

    注意如果用这个方案,还是要补上上面提到的导航控制器类型判断逻辑,否则当Segue连到导航控制器时依然会传值失败。

额外校验点

改完之后如果还是不显示数据,可以检查两点:

  • 目标页面的tableView的delegate、dataSource连线是否正常,Cell复用IDdetailIdentifier是否和Storyboard里配置的一致
  • 如果传值时机晚于viewDidLoad(比如用其他跳转方式),需要在给getDescriptions赋值后调用tableView.reloadData()刷新列表,当前代码用Segue的生命周期是先传值再走viewDidLoad,不需要额外调用刷新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 17:45:39