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

Swift开发:选中TableViewCell无法执行Segue跳转求助

问题求助:Swift UITableView 单元格点击跳转失败

我Swift开发经验不多,正在写代码学习。我的应用初始界面有多个按钮,点击可跳转到不同页面/功能,其中“Table View (CH Cantons)”按钮会打开一个带UITableView的视图,这个TableView要展示三个内容:

  • 州徽/州盾形纹章
  • 州名称(示例:ZH - Zurich)
  • 对应州的面积

选中州的单元格时,应该跳转到新页面展示该州详情,但试了好几种方法都没实现。另外想问:TableView必须放在主视图里吗?


相关代码

生成TableView的代码

let cantonsData = ["AG - Aargau","BE - Bern","GE - Geneve","GR -  Graubunden","JU - Jura","LU - Lucern","NE - Neuchâtel","SG - Sankt Gallen","TG - Thurgau","TI - Ticino","UR - Uri","VD - Vaud","VS - Valais","ZH - Zurich","AI - Appenzell \n Innerrhoden","AR - Appenzell \n Ausserrhoden","SH - Schaffhausen","BL - Basel \n Landschaft","BS - Basel","SO - Solothurn","FR - Fribourg","ZG - Zug","GL - Glarus","NW - Nidwald","OW - Obwald", "SZ - Schwyz"]
    
let area = ["Area (km2): 1404 km2","Area (km2): 5,960 km2","Area (km2): 1,792 km2","Area (km2): 7,105 km2","Area (km2): 839 km2","Area (km2): 1,494 km2","Area (km2): 802 km2 ","Area (km2): 2031 km2","Area (km2): 992 km2","Area (km2): 2812 km2","Area (km2): 1077 km2","Area (km2): 3212 km2","Area (km2): 5224 km2","Area (km2): 1729 km2","Area (km2): 172 km2","Area (km2): 243 km2","Area (km2): 298 km2","Area (km2): 518 km2","Area (km2): 37 km2","Area (km2): 790 km2","FR - Fribourg","ZG - Zug","GL - Glarus","NW - Nidwald","OW - Obwald", "SZ - Schwyz"]
    
override var modalPresentationStyle: UIModalPresentationStyle {
    get { .fullScreen }
    set { assertionFailure("Shouldnt change that 😠") }
}
    
override func viewDidLoad() {
    //super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    
    self.title = "CH Cantons / CH Kantons"
    tableView.dataSource = self
    tableView.delegate = self
    
    let nibName = UINib(nibName: "TableViewCell", bundle: nil)
    tableView.register(nibName, forCellReuseIdentifier: "tableViewCell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return cantonsData.count
}
    
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! TableViewCell
    
    cell.commonInit("CH-\(indexPath.item+1)", title: cantonsData[indexPath.item], sub: area[indexPath.item])
    return cell
}
    
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 180
}

单元格点击跳转代码(第一种尝试)

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let storyboard = UIStoryboard(name: "TableViewCH", bundle: nil)
    if let vc = storyboard.instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController{
        vc.img = UIImage(named: cantonsData[indexPath.item])!
        vc.canton = cantonsData[indexPath.row]
        self.navigationController?.pushViewController(vc, animated: true)
    }
}

第二种尝试代码

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath)
    tableView.deselectRow(at: indexPath, animated: true)
    performSegue(withIdentifier: "mySegue", sender: cell)
}

问题解答

关于TableView的位置疑问

TableView不需要必须放在主视图里,它可以放在任何UIViewController的视图层级中,只要正确设置数据源和代理,就能正常运行。

跳转失败的原因排查及解决办法

第一种跳转方法的问题

  1. 导航控制器为空
    你重写了modalPresentationStyle为全屏,说明当前TableView所在的VC是被modal出来的,不在导航栈中,调用navigationController?.pushViewController会直接失效。
    解决:要么用UINavigationController包裹这个VC后再modal,要么把跳转方式改为present(vc, animated: true)。

  2. 图片资源加载崩溃
    UIImage(named: cantonsData[indexPath.item])!用州名称字符串作为图片名,若文件名不匹配会返回nil,强行解包!会导致崩溃,中断跳转流程。
    解决:改用州代码(从cantonsData提取前两位)作为图片名,同时安全解包:

    if let imageName = cantonsData[indexPath.item].components(separatedBy: " - ").first,
       let image = UIImage(named: imageName) {
        vc.img = image
    }
    
  3. Storyboard或VC标识符错误
    确认UIStoryboard(name: "TableViewCH")的名称和实际storyboard文件名完全一致(注意大小写),同时DetailViewController的storyboard ID已正确设置。

第二种跳转方法的问题

  1. 方法签名错误
    Swift 3及以后,单元格点击方法的正确签名是func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath),你写的旧版本签名不会被系统调用,导致点击无反应。

  2. 缺少Segue数据传递逻辑
    用performSegue跳转时,必须实现prepare(for:sender:)方法传递数据:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard segue.identifier == "mySegue",
              let detailVC = segue.destination as? DetailViewController,
              let indexPath = tableView.indexPathForSelectedRow else { return }
        
        detailVC.canton = cantonsData[indexPath.row]
        if let imageName = cantonsData[indexPath.row].components(separatedBy: " - ").first,
           let image = UIImage(named: imageName) {
            detailVC.img = image
        }
    }
    
  3. Segue配置错误
    确认storyboard中segue的标识符为"mySegue",且segue是从当前TableViewVC指向DetailVC(或从单元格指向DetailVC)。

通用检查项

  • 确认tableView.delegate = self未被其他代码覆盖;
  • 检查TableViewCell的Selection属性不是None(需设为Default或Gray)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:33:27