如何通过Delegate模式点击CollectionViewCell按钮向TableView传数据
实现步骤与代码修正
1. 完善Delegate协议,添加数据传递方法
先给空的DataTransformationDelegate补充方法,用于传递当前Cell的数据和收藏状态:
protocol DataTransformationDelegate: AnyObject { // 传递收藏数据与状态 func didToggleFavorite(for data: YourDataModel, isFavorite: Bool) }
注意:把YourDataModel替换成你实际使用的数据模型类(需和MockData的模型结构一致)
2. 改造SlotCollectionViewCell,添加数据模型属性并触发Delegate
给Cell增加数据模型属性,点击收藏按钮时调用Delegate方法传递数据:
class SlotCollectionViewCell: UICollectionViewCell { @IBOutlet weak var title: UILabel! @IBOutlet weak var subtitle: UILabel! @IBOutlet weak var date: UILabel! @IBOutlet weak var favoriteButton: UIButton! @IBOutlet weak var thumbnail: UIImageView! weak var delegate: DataTransformationDelegate? // 添加数据模型属性,保存当前Cell对应的数据 var cellData: YourDataModel! { didSet { // 给Cell控件赋值 title.text = cellData.title subtitle.text = cellData.subtitle date.text = cellData.date // 可按需求自行处理日期格式 thumbnail.image = UIImage(named: cellData.thumbnail) // 初始化收藏状态(需确保模型有isFavorite属性,无则单独维护) favorite = cellData.isFavorite } } var favorite = false { didSet { let imageName = favorite ? "favoriteOn" : "favoriteOff" favoriteButton.setBackgroundImage(UIImage(named: imageName), for: .normal) } } override func awakeFromNib() { super.awakeFromNib() } @IBAction func favoriteButtonTapped(_ sender: UIButton) { favorite.toggle() // 调用Delegate传递数据与状态 delegate?.didToggleFavorite(for: cellData, isFavorite: favorite) } }
3. 在CollectionView所在控制器(ThumbnailCollectionViewController)实现Delegate
在ThumbnailCollectionViewController中给每个Cell设置Delegate,并通过闭包把数据传递回FavoriteTableViewController:
class ThumbnailCollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { // 定义闭包,用于向上传递收藏数据 var favoriteUpdateHandler: ((YourDataModel, Bool) -> Void)? func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SlotCollectionViewCell", for: indexPath) as! SlotCollectionViewCell let data = yourCollectionDataSource[indexPath.item] // 替换成你的Collection数据源数组 cell.cellData = data cell.delegate = self return cell } } // 实现DataTransformationDelegate协议 extension ThumbnailCollectionViewController: DataTransformationDelegate { func didToggleFavorite(for data: YourDataModel, isFavorite: Bool) { // 通过闭包把数据传递给FavoriteTableViewController favoriteUpdateHandler?(data, isFavorite) } }
4. 修改FavoriteTableViewController,维护收藏数据源并刷新TableView
将原来固定使用MockData的逻辑改为维护自定义收藏数组,同时接收来自CollectionView的数据:
class FavoriteTableViewController: UIViewController { @IBOutlet weak var tableView: UITableView! // 收藏数据数组,保存用户点击收藏的内容 private var favoriteData: [YourDataModel] = [] override func viewDidLoad() { super.viewDidLoad() tableView.register(UINib(nibName: String(describing: FavoriteTableViewCell.self), bundle: nil), forCellReuseIdentifier: String(describing: FavoriteTableViewCell.self)) tableView.delegate = self tableView.dataSource = self } @IBAction func toCollectionViewTapped(_ sender: Any) { let storyboard = UIStoryboard(name: String(describing: ThumbnailCollectionViewController.self), bundle: nil) let thumbnailCollectionVC = storyboard.instantiateViewController(withIdentifier: "ThumbnailCollectionViewController") as! ThumbnailCollectionViewController thumbnailCollectionVC.modalPresentationStyle = .fullScreen // 设置闭包,接收收藏数据并更新TableView thumbnailCollectionVC.favoriteUpdateHandler = { [weak self] data, isFavorite in guard let self = self else { return } if isFavorite { // 收藏时添加数据,避免重复(假设模型有id属性用于判断唯一性) if !self.favoriteData.contains(where: { $0.id == data.id }) { self.favoriteData.append(data) } } else { // 取消收藏时移除对应数据 self.favoriteData.removeAll(where: { $0.id == data.id }) } // 刷新TableView self.tableView.reloadData() } self.present(thumbnailCollectionVC, animated: true) } } extension FavoriteTableViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 90 } } extension FavoriteTableViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // 返回收藏数组的元素数量 return favoriteData.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: FavoriteTableViewCell.self), for: indexPath) as! FavoriteTableViewCell let currentDateTime = Date() let dateFormatter = DateFormatter() dateFormatter.timeStyle = .long let mockData = favoriteData[indexPath.row] cell.title.text = mockData.title cell.subtitle.text = mockData.subtitle cell.date.text = "\(dateFormatter.string(from: currentDateTime))" cell.thumbnail.image = UIImage(named: mockData.thumbnail) return cell } }
关键注意点
- 替换
YourDataModel为你实际的数据模型类,确保模型包含必要属性(比如id用于判断数据唯一性) - 确保
ThumbnailCollectionViewController中的yourCollectionDataSource是你的CollectionView实际数据源 - 使用
[weak self]避免循环引用 - 若需要持久化收藏数据,可将
favoriteData存入UserDefaults或本地数据库
内容的提问来源于stack exchange,提问作者Schocolate
相关产品推荐
相关产品推荐

