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
相关产品推荐
相关产品推荐

