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

Swift中点击嵌套collectionView cell内按钮push视图控制器的实现方法

解决方案

你可以通过两层闭包回调的方式实现事件传递,逻辑更简洁,不需要写多层代理:

步骤1:修改CollectionViewCell,添加按钮点击回调

在CollectionViewCell类中新增闭包属性,按钮点击时触发回调:

class CollectionViewCell: UICollectionViewCell {
    static let identifier = "HomeRecommendStoreCollectionViewCell"
    // 新增按钮点击回调闭包
    var buttonTapped: (() -> Void)?
    
    private lazy var listButton: UIButton = {
        let button = UIButton()
        return button
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setUp()
    }
    
    func setUp() {
        listButton.addTarget(self, action: #selector(onTap), for: .touchUpInside)
    }
    
    @objc func onTap() {
        // 点击时触发回调
        buttonTapped?()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

步骤2:修改TableViewCell,中转回调事件

在TableViewCell类中也新增回调闭包,在collectionView的cellForItem方法中将内层cell的回调传递到外层:

class TableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    
    static let identifier = "HomeRecommendStoreTableViewCell"
    // 新增对外回调闭包
    var collectionCellButtonTapped: (() -> Void)?
    
    private var collectionView: UICollectionView!
    
    // 原有初始化、布局代码保持不变...
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        guard let cell = collectionView.dequeueReusableCell(
            withReuseIdentifier: HomeRecommendStoreCollectionViewCell.identifier, for: indexPath
        ) as? HomeRecommendStoreCollectionViewCell else {
            return collectionView.dequeueReusableCell(
                withReuseIdentifier: "cell", for: indexPath
            )
        }
        // 绑定内层cell的回调
        cell.buttonTapped = { [weak self] in
            self?.collectionCellButtonTapped?()
        }
        return cell
    }
}

步骤3:主ViewController中监听回调,执行跳转逻辑

在主控制器的tableView cellForRow方法中监听TableViewCell的回调,执行push操作:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: HomePopularTableViewCell.identifier, for: indexPath) as? HomePopularTableViewCell else { return tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)}
    cell.selectionStyle = .none
    // 监听回调执行跳转
    cell.collectionCellButtonTapped = { [weak self] in
        let targetVC = TargetViewController() // 替换为你要跳转的目标控制器
        self?.navigationController?.pushViewController(targetVC, animated: true)
    }
    return cell
}

如果需要传递点击的cell对应的数据源,可以把闭包的参数改成对应的数据模型类型,回调时把对应indexPath的模型传出来即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 16:36:02