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

Swift中点击按钮实现不同ViewController的TableViewCell数据传递

解决思路与代码实现

首先明确:你要的是点击Cell内按钮触发数据传递,而非点击整个Cell(didSelectRowAt是点击Cell整体的回调),先把这两个触发场景区分开,再看具体实现。

一、Closure 实现方式(推荐)

1. 自定义源Cell(SourceCell)

给Cell内的按钮绑定点击事件,定义Closure用于向外传递数据:

import UIKit

class SourceCell: UITableViewCell {
    // 假设Cell展示的数据模型
    var dataModel: String? {
        didSet {
            textLabel?.text = dataModel
        }
    }
    
    // 定义Closure,用于传递数据
    var onButtonTap: ((String) -> Void)?
    
    // 按钮点击事件
    @IBAction func tapTransferButton(_ sender: UIButton) {
        guard let data = dataModel else { return }
        onButtonTap?(data) // 触发Closure,传递数据
    }
}

2. 源ViewController(SourceVC)

在cellForRowAt中绑定Closure,接收Cell传递的数据后,跳转到目标VC并传值:

class SourceVC: UIViewController, UITableViewDataSource {
    let dataList = ["数据1", "数据2", "数据3"]
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SourceCell", for: indexPath) as! SourceCell
        cell.dataModel = dataList[indexPath.row]
        
        // 绑定Closure
        cell.onButtonTap = { [weak self] transferredData in
            // 初始化目标VC,传递数据
            let targetVC = TargetVC()
            targetVC.receivedData = transferredData
            // 跳转(根据你的导航方式调整,比如push或present)
            self?.navigationController?.pushViewController(targetVC, animated: true)
        }
        return cell
    }
}

3. 目标ViewController(TargetVC)

接收数据并刷新自己的TableView:

class TargetVC: UIViewController, UITableViewDataSource {
    var receivedData: String?
    // 目标VC的数据源,这里把接收的数据加入列表
    var targetDataList = [String]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if let data = receivedData {
            targetDataList.append(data)
            tableView.reloadData() // 刷新TableView
        }
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return targetDataList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TargetCell", for: indexPath)
        cell.textLabel?.text = targetDataList[indexPath.row]
        return cell
    }
}

二、Delegate 实现方式

1. 定义Delegate协议

protocol SourceCellDelegate: AnyObject {
    func sourceCell(_ cell: SourceCell, didTapTransferButtonWith data: String)
}

2. 修改SourceCell

添加Delegate属性,按钮点击时调用Delegate方法:

class SourceCell: UITableViewCell {
    weak var delegate: SourceCellDelegate?
    var dataModel: String? {
        didSet {
            textLabel?.text = dataModel
        }
    }
    
    @IBAction func tapTransferButton(_ sender: UIButton) {
        guard let data = dataModel else { return }
        delegate?.sourceCell(self, didTapTransferButtonWith: data)
    }
}

3. SourceVC 遵守并实现Delegate

class SourceVC: UIViewController, UITableViewDataSource, SourceCellDelegate {
    let dataList = ["数据1", "数据2", "数据3"]
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SourceCell", for: indexPath) as! SourceCell
        cell.dataModel = dataList[indexPath.row]
        cell.delegate = self // 设置Delegate
        return cell
    }
    
    // 实现Delegate方法
    func sourceCell(_ cell: SourceCell, didTapTransferButtonWith data: String) {
        let targetVC = TargetVC()
        targetVC.receivedData = data
        navigationController?.pushViewController(targetVC, animated: true)
    }
    
    // 其余UITableViewDataSource方法同前
}

三、关于didSelectRowAt的困惑

  • tableView(_:didSelectRowAt:)是用户点击整个TableViewCell区域时触发的回调,和Cell内按钮的点击事件是两个独立的触发逻辑。
  • 如果你的需求是点击Cell整体就传值,那把传值逻辑写在这个方法里即可:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let selectedData = dataList[indexPath.row]
    let targetVC = TargetVC()
    targetVC.receivedData = selectedData
    navigationController?.pushViewController(targetVC, animated: true)
    tableView.deselectRow(at: indexPath, animated: true) // 可选:取消Cell选中状态
}
  • 如果你是点击Cell内按钮,这个方法不会自动执行,不用在里面写逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:45:33