iOS纯代码开发:如何点击表格单元格内自定义图片切换页面?
纯代码MVC架构下实现UITableViewCell内图片点击跳转页面的方案
一、自定义UITableViewCell(视图层)
- 创建继承自
UITableViewCell的自定义Cell类,比如CustomImageCell - 在Cell的初始化方法(
init(style:reuseIdentifier:))中:- 创建用于点击的
UIImageView实例,通过代码设置布局(AutoLayout或Frame) - 开启图片视图的交互能力:
imageView.isUserInteractionEnabled = true - 给图片视图添加点击手势:
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(imageTapped(_:))) imageView.addGestureRecognizer(tapGesture)
- 创建用于点击的
- 定义代理协议(用于向控制器传递点击事件):
protocol CustomImageCellDelegate: AnyObject { func customImageCell(_ cell: CustomImageCell, didTapImage indexPath: IndexPath) } - 在Cell中添加代理属性和存储位置的
indexPath属性:weak var delegate: CustomImageCellDelegate? var indexPath: IndexPath? - 实现手势触发方法,调用代理传递事件:
@objc private func imageTapped(_ gesture: UITapGestureRecognizer) { guard let indexPath = indexPath else { return } delegate?.customImageCell(self, didTapImage: indexPath) }
二、ViewController层(控制器层)
- 让ViewController遵守
UITableViewDataSource、UITableViewDelegate以及CustomImageCellDelegate协议 - 注册自定义Cell:
tableView.register(CustomImageCell.self, forCellReuseIdentifier: "CustomImageCellID") - 在
tableView(_:cellForRowAt:)方法中配置Cell:func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CustomImageCellID", for: indexPath) as! CustomImageCell // 从数据源数组取对应数据,设置Cell图片内容 cell.imageView.image = yourDataSourceArray[indexPath.row].image // 设置代理和当前indexPath cell.delegate = self cell.indexPath = indexPath return cell } - 实现代理方法,处理跳转逻辑:
func customImageCell(_ cell: CustomImageCell, didTapImage indexPath: IndexPath) { // 根据indexPath获取对应数据 let data = yourDataSourceArray[indexPath.row] // 创建目标页面的ViewController let targetVC = TargetViewController() // 向目标页面传递数据(可选) targetVC.targetData = data // 执行跳转:导航栈环境用push,否则用present navigationController?.pushViewController(targetVC, animated: true) // present(targetVC, animated: true) }
替代方案:用闭包传递点击事件
如果觉得代理流程繁琐,可改用闭包简化交互:
- 在自定义Cell中添加闭包属性:
var imageTapAction: ((IndexPath) -> Void)? - 修改手势触发方法:
@objc private func imageTapped(_ gesture: UITapGestureRecognizer) { guard let indexPath = indexPath else { return } imageTapAction?(indexPath) } - 在ViewController的
cellForRowAt中绑定闭包:cell.imageTapAction = { [weak self] indexPath in guard let self = self else { return } let data = self.yourDataSourceArray[indexPath.row] let targetVC = TargetViewController() targetVC.targetData = data self.navigationController?.pushViewController(targetVC, animated: true) }
核心原理
- 视图层(Cell)仅负责展示内容和捕获用户点击,不处理跳转等业务逻辑,符合MVC职责分离原则
- 通过代理或闭包将点击事件传递给控制器层(ViewController),由控制器统一处理页面导航和数据传递
- 纯代码开发模式下,所有视图组件(Cell、ImageView、手势)均通过代码创建配置,完全脱离Storyboard依赖
内容的提问来源于stack exchange,提问作者user16103051
相关产品推荐
相关产品推荐

